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])

 

 

你可能感兴趣的:(mac)