动态规划,多重背包
题目大意:
有各种不同面值的货币,每种面值的货币有不同的数量,请找出利用这些货币可以凑成的最接近且小于等于给定的数字cash的金额。
// Time 79ms; Memory 640K #include<iostream> using namespace std; int v,f[100010]; int max(int a,int b) { return a>b?a:b; } void zeroone_pack(int c) //01背包 { for(int i=v;i>=c;i--) if(!f[i]) { f[i]=f[i-c]; } } void complete_pack(int c) //完全背包 { for(int i=c;i<=v;i++) if(!f[i]) { f[i]=f[i-c]; } } void multiple_pack(int c,int n) //多重背包 { if(n>=v) { complete_pack(c);return; } int k=1; while(k<n) { zeroone_pack(c*k); n-=k; k*=2; } zeroone_pack(c*n); } int main() { int i,n,c,m; while(cin>>v>>m) { memset(f,0,sizeof(f)); f[0]=1; for(i=0;i<m;i++) { cin>>n>>c; multiple_pack(c,n); } for(i=v;i>=0;i--) if(f[i]) { cout<<i<<endl;break; } } return 0; }