poj 2484 Cow Exhibition 【变形0-1背包】

妖狐艹你老母 2022-08-13 13:50 110阅读 0赞

题目:poj 2484 Cow Exhibition

题意:给出n头牛,每头牛有一个幸运值 si 和聪明值 ti ,现在要选出一些牛,让两个值的和最大,前提是sum(si)和sum(ti)都是非负值。

分析:此题数据量不大,可以暴搜+剪枝水过。

这里要说的是0-1背包的思想,这个题目明显的变形就是物品有两个属性值,而且都要选最大的。

那么我们可不可以把一个值固定下来来求另一个值的最大值,根据0-1背包的思想,定义状态:dp【i】表示装入一些物品使得sum(si)的时候最大的sum(ti)的值。

那么状态转移方程为dp【i+si】 = max(dp【i+si】,dp【i】+ti) ,正好表示一个物品的两种选择。

ac代码:

  1. #include <cstdio>
  2. #include <cstring>
  3. #include <vector>
  4. using namespace std;
  5. const int N = 210000;
  6. const int pos = 100000;
  7. int dp[N];
  8. int main()
  9. {
  10. int n;
  11. while(~scanf("%d",&n))
  12. {
  13. memset(dp,-0x3f3f3f3f,sizeof(dp));
  14. dp[pos] = 0;
  15. int ma = pos,mi = pos;
  16. for(int i=0;i<n;i++)
  17. {
  18. int s,t;
  19. scanf("%d%d",&s,&t);
  20. if(s>0){
  21. for(int f=ma ;f>=mi;f--)
  22. dp[f+s] = max(dp[f+s],dp[f]+t);
  23. ma+=s;
  24. }
  25. else{
  26. for(int f = mi;f<=ma;f++)
  27. dp[f+s] = max(dp[f+s],dp[f]+t);
  28. mi+=s;
  29. }
  30. }
  31. int ans = 0;
  32. for(int i=pos;i<=ma;i++)
  33. if(dp[i]>=0)
  34. ans = max(ans,i-pos+dp[i]);
  35. printf("%d\n",ans);
  36. }
  37. return 0;
  38. }

搜索超时代码:

  1. #include <cstdio>
  2. #include <cstring>
  3. #include <vector>
  4. #include <algorithm>
  5. using namespace std;
  6. const int N = 210000;
  7. const int pos = 100000;
  8. struct Node
  9. {
  10. int s,t;
  11. };
  12. vector<Node> v;
  13. int cmp(Node a,Node b)
  14. {
  15. if(a.s!=b.s)
  16. return a.s>b.s;
  17. if(a.t!=b.t)
  18. return a.t>b.t;
  19. }
  20. int ans;
  21. void dfs(int i,int sums,int sumt)
  22. {
  23. if(i==v.size())
  24. return ;
  25. if(sums>=0 && sumt>=0)
  26. ans = max(ans,sums+sumt);
  27. if(sums<0 && v[i].s<=0)
  28. return ;
  29. dfs(i+1,sums,sumt);
  30. dfs(i+1,sums+v[i+1].s,sumt+v[i+1].t);
  31. }
  32. int main()
  33. {
  34. int n;
  35. int sums = 0,sumt = 0;
  36. while(~scanf("%d",&n))
  37. {
  38. for(int i=0;i<n;i++)
  39. {
  40. int s,t;
  41. scanf("%d%d",&s,&t);
  42. if(s>=0 && t>=0)
  43. {
  44. sums+=s,sumt+=t;
  45. }
  46. else if(s<=0 && t<=0)
  47. continue;
  48. else
  49. v.push_back((Node){s,t});
  50. }
  51. sort(v.begin(),v.end(),cmp);
  52. ans = 0;
  53. dfs(0,0,0);
  54. dfs(0,v[0].s,v[0].t);
  55. printf("%d\n",ans+sums+sumt);
  56. }
  57. return 0;
  58. }

发表评论

表情:
评论列表 (有 0 条评论,110人围观)

还没有评论,来说两句吧...

相关阅读

    相关 01背包问题 poj 3624

    理解01背包问题,首先要从二维数组的开始。二维数组的理解之后,优化成为一维,就是轻而易举的事了。 01背包动态规划的转移公式: 当考虑第i件物品的时候,背包能装得下的话