2120 : 安详
题目描述
spring最近喜欢上了B站新秀主播,身为顿顿吃黄焖鸡的土豪,当然要过去打赏一番,但是spring还是喜欢精打细算,所以在打赏的时候,想要掏出有限的钱,获得主播的最大好感。
主播的好感值是通过送不同的礼物而提升不同,不同礼物的赠送,可以增加的好感值也是不同的,当然礼物的价格更是不同。
输入
输入第一行为两个整数n,m.分别表示有n种不同礼物(1e2)和总金钱数m(1e6),以下n行每行有三个数字,分别表示该礼物的个数(int)和价格(int)以及好感值(int)。 多实例
输出
求spring拿出的钱可以送出的最大好感值。
样例输入
复制
2 10 4 2 100 2 4 100
样例输出
复制
400
多重背包解决思路:
题目:有N种物品和一个容量为V的背包。第i种物品最多有num[i]件可用,每件容量是c[i],价值是w[i]。
转换成01背包:二进制优化方法是:将第i种物品分成若干件物品,其中每件物品有一个系数,这件物品的容量和价值均是原来的容量和价值乘以这个系数。使这些系数分别为1,2,4,...,2^(k-1),(以及二进制尾数部分)num[i]-2^k+1,且k是满足num[i]-2^k+1>0的最大整数。例如,如果n[i]为13,就将这种物品分成系数分别为1,2,4,6的四件物品。
1 #define N 10008 2 #define M 1000008 3 4 ll dp[M]; 5 struct node{ 6 ll c,w; //c为cost,w为好感度 7 }p[N]; 8 9 int main(){ 10 11 ll nn,m; 12 while(scanf("%lld%lld",&nn,&m)!=EOF){ 13 int cnt=0;//拆分后的物品数 14 ll t,c,w; 15 16 for(int i=1;i<=nn;i++){ 17 scanf("%lld%lld%lld",&t,&c,&w); //数量,花费,好感度 18 int x=1; 19 while(t-x>0){ 20 t-=x; 21 p[++cnt].c=x*c; 22 p[cnt].w =x*w; 23 x*=2; 24 } 25 p[++cnt].c=t*c; //跑完上面的循环后剩下t 26 p[cnt].w=t*w; 27 } 28 29 memset(dp,0,sizeof(dp)); 30 for(int i=1;i<=cnt;i++){ 31 for(int j=m;j>=p[i].c;j--){ //花费自大到小 32 dp[j]=max(dp[j],dp[j-p[i].c]+p[i].w); 33 } 34 } 35 36 37 printf("%lld ",dp[m]); 38 } 39 40 return 0; 41 } 42 #define N 10008 43 #define M 1000008 44 45 ll dp[M]; 46 struct node{ 47 ll c,w; //c为cost,w为好感度 48 }p[N]; 49 50 int main(){ 51 52 ll nn,m; 53 while(scanf("%lld%lld",&nn,&m)!=EOF){ 54 int cnt=0;//拆分后的物品数 55 ll t,c,w; 56 57 for(int i=1;i<=nn;i++){ 58 scanf("%lld%lld%lld",&t,&c,&w); //数量,花费,好感度 59 int x=1; 60 while(t-x>0){ 61 t-=x; 62 p[++cnt].c=x*c; 63 p[cnt].w =x*w; 64 x*=2; 65 } 66 p[++cnt].c=t*c; //跑完上面的循环后剩下t 67 p[cnt].w=t*w; 68 } 69 70 memset(dp,0,sizeof(dp)); 71 for(int i=1;i<=cnt;i++){ 72 for(int j=m;j>=p[i].c;j--){ //花费自大到小 73 dp[j]=max(dp[j],dp[j-p[i].c]+p[i].w); 74 } 75 } 76 77 78 printf("%lld ",dp[m]); 79 } 80 81 return 0; 82 }