前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Google Code Jam 2020 Qualification Round: Vestigium Solution

Google Code Jam 2020 Qualification Round: Vestigium Solution

作者头像
包子面试培训
发布2020-05-21 09:52:29
7270
发布2020-05-21 09:52:29
举报
文章被收录于专栏:包子铺里聊IT包子铺里聊IT

Google Code Jam 2020 Qualification Round: Vestigium Solution

Blogger: http://blog.baozitraining.org/2020/05/google-code-jam-2020-qualification.html

Youtube: https://youtu.be/oipVOvqkFVc

博客园: https://www.cnblogs.com/baozitraining/p/12866601.html

B站: https://www.bilibili.com/video/BV16z4y1R7k6/

Problem Statement

Problem

Dr. Patel has N stacks of plates. Each stack contains K plates. Each plate has a positive beauty value, describing how beautiful it looks.

Dr. Patel would like to take exactly P plates to use for dinner tonight. If he would like to take a plate in a stack, he must also take all of the plates above it in that stack as well.

Help Dr. Patel pick the P plates that would maximize the total sum of beauty values.

Input

The first line of the input gives the number of test cases, T. T test cases follow. Each test case begins with a line containing the three integers N, K and P. Then, N lines follow. The i-th line contains K integers, describing the beauty values of each stack of plates from top to bottom.

Output

For each test case, output one line containing Case #x: y, where x is the test case number (starting from 1) and y is the maximum total sum of beauty values that Dr. Patel could pick.

Limits

Time limit: 20 seconds per test set.

Memory limit: 1GB.

1 ≤ T ≤ 100.

1 ≤ K ≤ 30.

1 ≤ PN * K.

The beauty values are between 1 and 100, inclusive.

Test set 1

1 ≤ N ≤ 3.

Test set 2

1 ≤ N ≤ 50.

Sample

Input

Output

22 4 510 10 100 3080 50 10 503 2 380 8015 5020 10

Case #1: 250Case #2: 180

In Sample Case #1, Dr. Patel needs to pick P = 5 plates:

  • He can pick the top 3 plates from the first stack (10 + 10 + 100 = 120).
  • He can pick the top 2 plates from the second stack (80 + 50 = 130) .

In total, the sum of beauty values is 250.

In Sample Case #2, Dr. Patel needs to pick P = 3 plates:

  • He can pick the top 2 plates from the first stack (80 + 80 = 160).
  • He can pick no plates from the second stack.
  • He can pick the top plate from the third stack (20).

In total, the sum of beauty values is 180.

Note: Unlike previous editions, in Kick Start 2020, all test sets are visible verdict test sets, meaning you receive instant feedback upon submission.

Problem link

Video Tutorial

You can find the detailed video tutorial here

  • Youtube
  • B站

Thought Process

First thought is similar to merging multiple lists, this won't work since the lists are not sorted and we are not allowed to sort due to the order constraint.

Second thought is keep a max heap, and always merge the largest value from all the top elements in the lists. This is wrong since greedy won't work here. E.g., below if we want to pick 3 plates, using max heap will pick 2, 2, 2, instead of 1, 1, 100

2, 2, 2, 2, 2

1, 1, 100, 100, 100

Third thought seems we have to brute force, for all the combos of P, we check what's the maximum value. Quote from the analysis, it's exponential time complexity

For example, if N = 3 and for any given values of K and P, generate all possible triples (S1, S2, S3) such that S1+S2+S3 = P and 0 ≤ Si ≤ K. Note: Si is the number of plates picked from the i-th stack. This can be done via recursion and the total time complexity is O(KN) which abides by the time limits.

Forth and final solution to optimize this is using dynamic programming. It's very common in those coding competitions.

Quote from the analysis

First, let's consider an intermediate state dp[i][j] which denotes the maximum sum that can be obtained using the first i stacks when we need to pick j plates in total.

Next, we iterate over the stacks and try to answer the question: What is the maximum sum if we had to pick j plates in total using the i stacks we've seen so far? This would give us dp[i][j]. However, we need to also decide, among those j plates, how many come from the i-th stack? i.e., Let's say we pick x plates from the i-th stack, then dp[i][j] = max(dp[i][j], sum[i][x]+dp[i-1][j-x]). Therefore, in order to pick j plates in total from i stacks, we can pick anywhere between [0, 1, ..., j] plates from the i-th stack and [j, j-1, ..., 0] plates from the previous i-1 stacks respectively. Also, we need to do this for all values of 1 ≤ jP. The flow would look like: for i [1, N]:  for j [0, P]:   dp[i][j] := 0    for x [0, min(j, K)]:     dp[i][j] = max(dp[i][j], sum[i][x]+dp[i-1][j-x]) If we observe closely, this is similar to the 0-1 Knapsack Problem with some added complexity. To conclude, the overall time complexity would be O(N*P*K).

Solutions

代码语言:javascript
复制
 1 public static void main(String[] args) {
 2     Scanner s = new Scanner(new BufferedReader(new InputStreamReader(System.in)));
 3 
 4     int testCases = s.nextInt();
 5     int caseNum = 1;
 6     Plates plates = new Plates();
 7 
 8     while (caseNum <= testCases) {
 9         int n = s.nextInt();
10         int k = s.nextInt();
11         int p = s.nextInt();
12 
13         int[][] values = new int[n][k];
14         for (int i = 0; i < n; i++) {
15             for (int j = 0; j < k; j++) {
16                 values[i][j] = s.nextInt();
17             }
18         }
19 
20         System.out.println(String.format("Case #%d: %d", caseNum, plates.maxPlatesBeautyValue(values, p)));
21         caseNum++;
22     }
23 }
24 
25 private int maxPlatesBeautyValue(int[][] values, int numberOfPlates) {
26     int n = values.length;
27     int k= values[0].length;
28     int p = numberOfPlates;
29 
30 
31     // could use a one dimension array
32     int[][] prefixSum = new int[n + 1][k + 1];
33     int[][] lookup = new int[n + 1][p + 1];
34 
35     for (int i = 1; i <= n; i++) {
36         for (int j = 1; j <= k; j++) {
37             prefixSum[i][j] = prefixSum[i][j - 1] + values[i - 1][j - 1];
38         }
39     }
40 
41     for (int i = 1; i <= n; i++) {
42         for (int j = 1; j <= p; j++) {
43             lookup[i][j] = 0;
44 
45             for (int x = 0; x <= Math.min(j, k); x++) {
46                 lookup[i][j] = Math.max(lookup[i][j], prefixSum[i][x] + lookup[i - 1][j - x]);
47             }
48         }
49     }
50 
51     return lookup[n][p];
52 }
DP solution

Time Complexity: O(N*P*K)

Space Complexity: O(N*max(P, K))

References

  • Google kickstart official solution
本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-05-17,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 包子铺里聊IT 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Problem Statement
  • Problem
  • Input
  • Output
  • Limits
    • Test set 1
      • Test set 2
      • Sample
      • Video Tutorial
      • Thought Process
      • Solutions
        • DP solution
        • References
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档