poj 1276 Cash Machine 题解
【算法】动态规划 【难度】★★★☆☆
本题是一道背包问题。很显然题目为多重背包。但是本题的数据量太大,朴素做法会超时。参考背包九讲的思路,拆分物品,处理成1,2,4,8,……,2n件物品。
这道题做了一周= =。。。犯了很多沙茶错误。。。T_T >_<
P.S.此题可以作为背包拆分物品的模板了
View Code
1 #include<stdio.h> 2 #include <stdlib.h> 3 #define bigger(a,b) (a>b?a:b) 4 int f[1000000+1]; 5 int cash,n,am[100+1],v[100+1]; 6 int w[10*1000+1],c[10*1000+1]; 7 int main() 8 { 9 while (scanf("%d%d",&cash,&n)!=EOF) 10 { 11 int i,j,k,e; 12 for (i=1; i<=n; i++) 13 scanf("%d%d",&am[i],&v[i]); 14 //初始化,恰好装满 15 f[0]=0; 16 for (i=1; i<1000000+1; i++) f[i]=-9999999; 17 //拆分物品***** 18 e=1; 19 for (i=1; i<=n; i++) 20 { 21 int k=1; 22 while (am[i]-k>=0) 23 { 24 am[i]-=k; 25 c[e]=k; 26 w[e++]=k*v[i]; 27 k*=2; 28 } 29 if (am[i]>0) {c[e]=k;w[e++]=am[i]*v[i];} 30 } 31 //0/1背包 32 for (i=1; i<e; i++) 33 for (j=cash; j>=0; j--) 34 if (j-w[i]>=0) f[j]=bigger(f[j-w[i]]+c[i],f[j]); 35 //寻找答案 36 for (i=cash; i>=0; i--) 37 if (f[i]>=0) 38 {printf("%d\n",i);break;} 39 //清空数组 40 for (i=0;i<=e+100;i++) 41 { 42 w[i]=c[i]=0; 43 for (j=0;j<cash+1;j++) f[j]=0; 44 } 45 for(i=0;i<100+1;i++) 46 am[i]=v[i]=0; 47 } 48 return 0; 49 } 50 //f[i][j]=max{f[i-1][j-k*v[i]]+k*w[i]}; 51 //(f[i-1][j-w[i]]+1,f[i-1][j])
wsc500原创,转载请注明出处。请注明 出自http://www.cnblogs.com/loveidea/