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 }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步