[Kick Start 2020] Round A 2.Plates

[Kick Start 2020] Round A 2.Plates

1. 題目

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 ≤ P ≤ N * 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

2
2 4 5
10 10 100 30
80 50 10 50
3 2 3
80 80
15 50
20 10

Case #1: 250
Case #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.

2. 思路

  • 感觸:發現好多知識點還沒學習到,經典的揹包系列問題
  • 思路:分組揹包問題,動態規劃的思路
    • 分組揹包問題: f[k][v]表示前k組獲得v個盤子能取得的最大值
    • 不取這個分組和取這個分組的最大值;如果取這個分組判斷取哪個能獲得最大的利益
    • f[k][v]=max{f[k-1][v],f[k-1][v-c[i]]+w[i]|物品i屬於組k}

3. 代碼

#include<iostream>
#include<fstream>
#include<vector>
#include<algorithm>
using namespace std;

int main(int argc, const char * argv[]) {
    // insert code here...
    int testNum, groupNum, groupPlateNum, needPlateNum;
    cin >> testNum;

    for (int i = 0; i < testNum; i++) {
        cin >> groupNum >> groupPlateNum >> needPlateNum;
        int** f = new int*[groupNum];
        int** w = new int*[groupNum];
        for (int j = 0; j < groupNum; j++) {
            f[j] = new int[needPlateNum+1];
            for (int m = 0; m <= needPlateNum; m++)
                f[j][m] = 0;
            w[j] = new int[groupPlateNum];
            int accu = 0;
            int onePlateV;
            for (int k = 0; k < groupPlateNum; k++) {
                cin >> onePlateV;
                accu += onePlateV;
                w[j][k] = accu;
            }
        }
        
        for (int j = 0; j < groupNum; j++) {
            for (int k = needPlateNum; k >= 0; k--) {
                int maxTemp = 0;
                for (int m = 0; m < groupPlateNum; m++) {
                    if (j >0 && k-m-1 >= 0) {
                        maxTemp = max(maxTemp, f[j-1][k-m-1]+w[j][m]);
                    }   
                    if (j == 0) {
                        if ((m+1)<=needPlateNum)
                            f[j][m+1] = w[j][m];
                    }
                }
                if (j != 0)
                    f[j][k] = max(f[j-1][k], maxTemp);
            }
        }
        cout << "Case #" << i+1 << ": " << f[groupNum-1][needPlateNum] << endl;
    }
    
    return 0;
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章