0-1背包问题

来源:互联网 发布:如何下载淘宝数据包 编辑:程序博客网 时间:2024/06/15 07:04

题意:给了n个物品,每个物品有两个值,H和C 问你怎么取, 使最后$$(\sum_{i=1}^{m} H_{x_i})^2-(\sum_{i=1}^{m} H_{x_i})\times(\sum_{i=1}^{m} C_{x_i})-(\sum_{i=1}^{m} C_{x_i})^2$$

这个东西最大。


分析:dp[i] 表示 取到C的总和为i的时候 使答案最大的 H的和为多少,剩下就和背包差不多了,需要注意的是dp值的初始化,需要取成-inf;


以下是代码:

[cpp] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. #include<iostream>  
  2. #include<cstdio>  
  3. #include<algorithm>  
  4. #include<queue>  
  5. #include<map>  
  6. #include<set>  
  7. #include<stack>  
  8. #include<cstring>  
  9. #include<string>  
  10. #include<vector>  
  11. #include<iomanip>  
  12. #include<unordered_set>  
  13. #include<unordered_map>  
  14. #include<cmath>  
  15. #include<list>  
  16. #include<bitset>  
  17. using namespace std;  
  18.   
  19. #define ull unsigned long long  
  20. #define ll long long  
  21. #define lson l,mid,id<<1  
  22. #define rson mid+1,r,id<<1|1  
  23.   
  24. typedef pair<intint>pii;  
  25. typedef pair<ll, ll>pll;  
  26. typedef pair<doubledouble>pdd;  
  27. const double eps = 1e-6;  
  28. const int MAXN = 100005;  
  29. const int MAXM = 5005;  
  30. const ll LINF = 0x3f3f3f3f3f3f3f3f;  
  31. const int INF = 0x3f3f3f3f;  
  32. const double FINF = 1e18;  
  33. const ll MOD = 1000000007;  
  34. ll dp[50005], h[505], c[505];  
  35. int main()  
  36. {  
  37.     int t, n;  
  38.     ll sum = 0;  
  39.     scanf("%d", &t);  
  40.     while (t--)  
  41.     {  
  42.         sum = 0;  
  43.         fill(dp, dp + 50001, -LINF);  
  44.         scanf("%d", &n);  
  45.         for (int i = 1; i <= n; ++i)scanf("%lld%lld", &h[i], &c[i]), sum += c[i];  
  46.         dp[0] = 0;  
  47.         for (int i = 1; i <= n; ++i)  
  48.         {  
  49.             for (int j = sum; j >= c[i]; --j)  
  50.             {  
  51.                 if (dp[j - c[i]] != -LINF)  
  52.                 {  
  53.                     if (dp[j] == -LINF)dp[j] = dp[j - c[i]] + h[i];  
  54.                     else  
  55.                     {  
  56.                         ll tmp = dp[j - c[i]] + h[i];  
  57.                         if (dp[j] * dp[j] - j*dp[j] - j*j < tmp*tmp - j*tmp - j*j)  
  58.                         {  
  59.                             dp[j] = tmp;  
  60.                         }  
  61.                     }  
  62.                 }  
  63.             }  
  64.         }  
  65.         ll ans = 0;  
  66.         for (int i = 0; i <= sum; ++i)  
  67.         {  
  68.             if (dp[i] != -LINF)  
  69.             {  
  70.                 ans = max(ans, dp[i] * dp[i] - i*dp[i] - i*i);  
  71.             }  
  72.         }  
  73.         cout << ans << endl;  
  74.     }  
  75. }  
0 0
原创粉丝点击