poj 1276 Cash Machine 题解

【算法】动态规划 【难度】★★★☆☆


本题是一道背包问题。很显然题目为多重背包。但是本题的数据量太大,朴素做法会超时。参考背包九讲的思路,拆分物品,处理成1,2,4,8,……,2件物品。

这道题做了一周= =。。。犯了很多沙茶错误。。。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])

 

 

posted @ 2012-04-26 20:14  wsc500  阅读(288)  评论(0编辑  收藏  举报