zoukankan      html  css  js  c++  java
  • HDU 5410 CRB and His Birthday ——(完全背包变形)

      对于每个物品,如果购买,价值为A[i]*x+B[i]的背包问题。

      先写了一发是WA的= =。代码如下:

     1 #include <stdio.h>
     2 #include <algorithm>
     3 #include <string.h>
     4 #include <set>
     5 using namespace std;
     6 typedef pair<int,int> pii;
     7 
     8 pii dp[2005];
     9 int w[1005],A[1005],B[1005];
    10 
    11 int main()
    12 {
    13     int T;scanf("%d",&T);
    14     while(T--)
    15     {
    16         int m,n;scanf("%d%d",&m,&n);
    17         for(int i=1;i<=n;i++) scanf("%d%d%d",w+i,A+i,B+i);
    18         for(int i=0;i<=m;i++) dp[i] = pii(0,0);
    19         for(int i=1;i<=n;i++)
    20         {
    21             for(int j=0;j<=m;j++) dp[j] = pii(dp[j].first, 0);
    22             for(int j=w[i];j<=m;j++)
    23             {
    24                 if(dp[j-w[i]].first + A[i] + (dp[j-w[i]].second == 0 ? B[i] : 0) > dp[j].first)
    25                 {
    26                     dp[j].first = dp[j-w[i]].first + A[i] + (dp[j-w[i]].second == 0 ? B[i] : 0);
    27                     dp[j].second = 1;
    28                 }
    29             }
    30         }
    31         printf("%d
    ",dp[m].first);
    32     }
    33     return 0;
    34 }

      

      正解是,先跑一遍价值为A[i]+B[i]的01背包,再跑一遍价值为A[i]完全背包。所以上面的代码错了大概是因为,这两个背包的第二个for的方向是不同的,没办法一起跑吧(除非用另外一组变量记录下到前一个为止的dp值,然后就可以同时跑了)。。对背包问题的理解还是不够深啊。。

    ————————————————————————————————————————————————————————

      想了一下,感觉上面说的括号里的再用一个数组记录的方法貌似不太对。。虽然那份代码AC了- -。。反正跑两遍的方法肯定是对的。。我说的是这个博客里面的第二个方法:http://www.cnblogs.com/wmxl/p/4749780.html。也有可能是我对完全背包的理解不够深刻。。先放着再说好了。。

    ————————————————————————————————————————————————————————

      AC代码如下:

     1 #include <stdio.h>
     2 #include <algorithm>
     3 #include <string.h>
     4 #include <set>
     5 using namespace std;
     6 typedef pair<int,int> pii;
     7 
     8 int dp[2005];
     9 int w[1005],A[1005],B[1005];
    10 
    11 int main()
    12 {
    13     int T;scanf("%d",&T);
    14     while(T--)
    15     {
    16         int m,n;scanf("%d%d",&m,&n);
    17         for(int i=1;i<=n;i++) scanf("%d%d%d",w+i,A+i,B+i);
    18         memset(dp,0,sizeof(dp));
    19         for(int i=1;i<=n;i++)
    20         {
    21             for(int j=m;j>=w[i];j--) dp[j] = max(dp[j], dp[j-w[i]] + A[i] + B[i]);
    22             for(int j=w[i];j<=m;j++) dp[j] = max(dp[j], dp[j-w[i]] + A[i]);
    23         }
    24         printf("%d
    ",dp[m]);
    25     }
    26     return 0;
    27 }
  • 相关阅读:
    LightOJ
    Peter and Snow Blower
    Gena's Code
    nyoj139--我排第几个 (康拓展开)
    hdoj1394(归并排序)
    树状数组
    Poj 1113--Wall(凸集)
    hdoj1437 -- 天气情况
    hdoj1428 -- 漫步校园 (记忆化搜索)
    图像边缘检测
  • 原文地址:https://www.cnblogs.com/zzyDS/p/6188175.html
Copyright © 2011-2022 走看看