HDU 5410 CRB and His Birthday ——(完全背包变形)

时间:2021-09-12 18:41:06

  对于每个物品,如果购买,价值为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\n",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\n",dp[m]);
25     }
26     return 0;
27 }