1 100 2 10 2 1 20 1 1
21HintCRB's mom buys 10 presents of first kind, and receives 2 × 10 + 1 = 21 candies.
题意:CRB生日,妈妈要给他买礼物,妈妈有M元钱,这家店有N种礼物,因为店长和妈妈是熟人,所以若第i种礼物买x件的话,店长会给妈妈Ai*x+Bi颗糖果,现给出每种礼物的单价、Ai值与Bi值,问妈妈最多能拿到多少颗糖果。
放上出题人的解题报告解题思路:刚拿到这题的时候就知道是完全背包的问题,因为每件礼物的数量无限多,我可以不取、取一件或取多件;而01背包的话是每种商品只有取或不取,没有多件之说;至于多重背包,则是每件商品的件数是有限的,告诉你的。关于完全背包,不懂的可以点链接,表示这个人讲解得挺好的。
该题知道是完全背包之后,问题还并没有解决,因为单种礼物能获得的糖果数与购买的礼物件数成线性关系,所以一件与多件的差距在于a[i]的倍数,而买或不买的差距则在于a[i]+b[i]。因此,b[i]的贡献仅在于买该种礼物的第一件
提供几组样例参考
Input
100
100 2
10 2 1
10 1 2
Output
22
Input
100
50 3
10 0 1
15 0 2
11 0 2
Output
5
#pragma comment(linker, "/STACK:1024000000,1024000000") #include<stdio.h> #include<string.h> #include<stdlib.h> #include<queue> #include<math.h> #include<vector> #include<map> #include<set> #include<stdlib.h> #include<cmath> #include<string> #include<algorithm> #include<iostream> #define exp 1e-10 using namespace std; const int N = 1005; const int inf = 1000000000; const int mod = 1000000007; int s[N*2][2],w[N],a[N],b[N]; int main() { int t,m,n,i,j; scanf("%d",&t); while(t--) { scanf("%d%d",&m,&n); memset(s,0,sizeof(s)); for(i=1; i<=n; i++) scanf("%d%d%d",&w[i],&a[i],&b[i]); for(i=1; i<=n; i++) for(j=0; j<=m; j++) { s[j][0]=max(s[j][0],s[j][1]); if(j>=w[i]) s[j][1]=max(s[j-w[i]][0]+a[i]+b[i],s[j-w[i]][1]+a[i]); else s[j][1]=0; } printf("%d\n",max(s[m][0],s[m][1])); } return 0; }菜鸟成长记