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\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 }
时间: 2024-10-12 16:40:26

HDU 5410 CRB and His Birthday ——(完全背包变形)的相关文章

hdu 5410 CRB and His Birthday(混合背包)

Problem Description Today is CRB's birthday. His mom decided to buy many presents for her lovely son. She went to the nearest shop with M Won(currency unit). At the shop, there are N kinds of presents. It costs Wi Won to buy one present of i-th kind.

hdu 5410 CRB and His Birthday 01背包和完全背包

#include<stdio.h> #include<string.h> #include<vector> #include<queue> #include<algorithm> using namespace std; int main() { int _,i,j,m,n,k,a[1024],b[1024],w[1024],dp[2048]; scanf("%d\n",&_); while(_--) { scanf(

HDU 5410 CRB and His Birthday (01背包,完全背包,混合)

题意:有n种商品,每种商品中有a个糖果,如果买这种商品就送多b个糖果,只有第一次买的时候才送.现在有m元,最多能买多少糖果? 思路:第一次买一种商品时有送糖果,对这一次进行一次01背包,也就是只能买一次.然后对这种商品来一次完全背包,此时不送糖果,也可以多买. 1 #include <bits/stdc++.h> 2 #define pii pair<int,int> 3 #define INF 0x7f7f7f7f 4 #define LL long long 5 using n

HDU 5410 CRB and His Birthday

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5410 Problem Description Today is CRB's birthday. His mom decided to buy many presents for her lovely son.She went to the nearest shop with M Won(currency unit).At the shop, there are N kinds of presents

hdu 5410 CRB and His Birthday(动态规划)

题目: CRB and His Birthday Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 748    Accepted Submission(s): 395 Problem Description Today is CRB's birthday. His mom decided to buy many presents for

HDOJ 5410 CRB and His Birthday DP背包

先跑一遍01背包,再跑一遍多重背包 CRB and His Birthday Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 327    Accepted Submission(s): 177 Problem Description Today is CRB's birthday. His mom decided to buy man

HDU 5410 CRB and His Birthday(DP)

CRB and His Birthday Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 83    Accepted Submission(s): 45 Problem Description Today is CRB's birthday. His mom decided to buy many presents for her l

HDU 5410 CRB and His Birthday (2015年多校比赛第10场)

1.题目描述:点击打开链接 2.解题思路:本题是完全背包问题的一种变形.根据题意描述,每种物品的价值随着A[i]是线性变化的,但是并不随着B[i]线性变化,B[i]仅仅是在第一次挑选第i件物品是才算入,其他时候均不算入.因此,这里的状态要比普通的完全背包增加一个维度:是否是第一次选第i件物品,即用(i,j,flag)表示当前背包容量为j时,是否为第一次选第i件物品时的最大价值.那么不难得到如下状态转移方程: dp(i+1,j,0)=max{dp(i,j,0),dp(i,j,1)}; dp(i+1

HDU 5410(2015多校10)-CRB and His Birthday(完全背包)

题目地址:HDU 5410 题意:有M元钱,N种礼物,若第i种礼物买x件的话,会有Ai*x+Bi颗糖果,现给出每种礼物的单价.Ai值与Bi值,问最多能拿到多少颗糖果. 思路:完全背包问题. dp[j][1]在当前物品时花钱为j的并且买过当前物品的最大值. dp[j][0]不买当前这件物品此前花钱为j的的最大值. 每种物品的价值随Ai线性变化,但是不随B[i]线性变化,B[i]仅是在第一次挑选第i件物品是才算入,其他时候均不算入.所以我们可以写出状态转移方程: dp[j][0]=max(dp[j]