poj1276Cash Machine

http://poj.org/problem?id=1276

第一种解法  http://blog.csdn.net/lyy289065406/article/details/6648102

代码

View Code
 1 #include <iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<stdlib.h>
 5 using namespace std;
 6 int c[20],w[20],num[20],cc[100010],dp[100010];
 7 int main()
 8 {
 9     int i,n,vv,v,g;
10     while(cin>>vv>>n)
11     {
12         g = 0;
13         for(i = 1; i <= n ; i++)
14         {
15             cin>>num[i]>>w[i];
16             c[i] = w[i];
17         }
18         memset(dp,0,sizeof(dp));
19         for(i = 1; i <= n ; i++)
20         {
21             memset(cc,0,sizeof(cc));
22             for(v = w[i] ; v <= vv ; v++)
23             if(dp[v]<(dp[v-c[i]]+w[i])&&cc[v-c[i]]<num[i])
24             {
25                 dp[v] = dp[v-c[i]]+w[i];
26                 cc[v] = cc[v-c[i]]+1;
27             }
28         }
29         cout<<dp[vv]<<endl;
30     }
31     return 0;
32 }

第二种解法 CZ教的 把问题转换为01背包 把每件物品的个数转换为2进制数 比如 10 转成1 2 4 3这样能保证 每个数都能由这几个数组合成。
dp[0] = 1;

从大道小遍历一遍 第一个为1 的即为最接近的

View Code
 1 #include <iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<stdlib.h>
 5 #include<cmath>
 6 using namespace std;
 7 int c[20],w[20],p[500],dp[100010];
 8 int main()
 9 {
10     int i,j,k,n,v,g;
11     while(cin>>v>>n)
12     {
13         memset(dp,0,sizeof(dp));
14         g = 0;
15         for(i = 1 ;i <= n ; i++)
16         cin>>c[i]>>w[i];
17         for(i = 1; i <= n ; i++)
18         {
19             k = 0;
20             while(c[i])
21             {
22                 if(c[i]>pow(2,k))
23                 {
24                     c[i]-=pow(2,k);
25                     g++;
26                     p[g] = pow(2,k)*w[i];
27                 }
28                 else
29                 {
30                     g++;
31                     p[g] = c[i]*w[i];
32                     break;
33                 }
34                 k++;
35             }
36         }
37         dp[0] = 1;
38         for(i = 1; i <= g ; i++)
39             for(j = v ; j >= p[i] ; j--)
40                 if(dp[j]<dp[j-p[i]])
41                    dp[j] = dp[j-p[i]];
42         for(i = v ; i >= 1 ; i--)
43         if(dp[i]==1)
44         break;
45         cout<<i<<endl;
46     }
47     return 0;
48 }

 

posted @ 2013-01-29 17:06  _雨  阅读(277)  评论(0编辑  收藏  举报