poj1276Cash Machine
http://poj.org/problem?id=1276
第一种解法 http://blog.csdn.net/lyy289065406/article/details/6648102
代码
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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 的即为最接近的
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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 }