ZOJ 4019 Schrödinger's Knapsack (from The 18th Zhejiang University Programming Contest Sponsored by TuSimple)

题意:

  第一类物品的价值为k1,第二类物品价值为k2,背包的体积是 c ,第一类物品有n 个,每个体积为S11,S12,S13,S14.....S1n ; 第二类物品有 m 个,每个体积为 S21,S22,S23,S24.......S2m;

每次装入物品时,得到的价值是 剩余背包体积*该类物品的价值;问最多能得到的总价值是多少。

思路:

  要想得到最大的总价值,肯定要从小的开始装,然后分别枚举第一类,第二类装进去的最大体积,还有将两类回合装入背包的最大体积,得到最后的答案

  我们用dp[i][j],来表示 1 - i 的第一种物品区间,1 - j 的第二种物品区间,即装入 1到 i 的一类物品和 1 到 j 的二类物品的所得到的最大价值

 1 #include <iostream>
 2 #include <algorithm>
 3 using namespace std;
 4 const int maxn = 2005;
 5 typedef long long ll;
 6 
 7 int t;
 8 ll dp[maxn][maxn];
 9 ll c1, c2, c;
10 ll v1[maxn], v2[maxn], sum1[maxn], sum2[maxn];
11 
12 int main(){
13     cin >> t;
14     while (t--){
15         cin >> c1 >> c2 >> c;
16         int  n, m;
17         cin >> n >> m;
18 
19         for (int i = 1; i <= n; i++)
20             cin >> v1[i];
21         for (int i = 1; i <= m; i++)
22             cin >> v2[i];
23 
24         sort(v1 + 1, v1 + 1 + n); 
25         sort(v2 + 1, v2 + 1 + m);
26         for (int i = 1; i <= n; i++)
27             sum1[i] = sum1[i - 1] + v1[i];
28         for (int i = 1; i <= m; i++)
29             sum2[i] = sum2[i - 1] + v2[i];
30 
31         for (int i = 0; i <= n; i++)
32         for (int j = 0; j <= m; j++) 
33             dp[i][j] = 0;
34 
35         ll ans = 0;
36         for (int i = 1; i <= n; i++)
37         if (sum1[i] <= c){
38             dp[i][0] = c1*(c - sum1[i]) + dp[i - 1][0];
39             ans = max(ans, dp[i][0]);
40         }
41         for (int j = 1; j <= m; j++)
42         if (sum2[j] <= c){
43             dp[0][j] = c2*(c - sum2[j]) + dp[0][j - 1];
44             ans = max(ans, dp[0][j]);
45         }
46 
47 
48         for (int i = 1; i <= n; i++)
49         for (int j = 1; j <= m; j++)
50         {
51             ll cnt = sum1[i] + sum2[j];
52             if (cnt <= c)
53             {
54                 dp[i][j] = max(dp[i - 1][j] + c1*(c - cnt), dp[i][j - 1] + c2*(c - cnt));
55                 ans = max(ans, dp[i][j]);
56             }
57         }
58         cout << ans << endl;
59     }
60     return 0;
61 }

 

posted @ 2018-04-08 20:27  ouyang_wsgwz  阅读(230)  评论(0编辑  收藏  举报