Cash MachinePOJ - 1276
cash N n1 D1 n2 D2 ... nN DN
最大面值和cash,面值数N,面值Di有ni张
对给定数据,最大不超过cash,可以凑多少钱
分析:
一种物品——一个面值
物品质量——面值
不超过最大质量——不超过最大面值
物品价值——面值
最大价值——最大面值和
注意这里面值既是质量也是价值, 就是一个简单的多重背包问题
代码:
#include<iostream> #include<cstdio> #include<cmath> #include<cstring> #include<string> #include<algorithm> #include<vector> #include<queue> #include<map> #include<stack> #include<set> #include<bitset> #include<list> #define UP(i,x,y) for(int i=x;i<=y;i++) #define DOWN(i,x,y) for(int i=x;i>=y;i--) #define MEM(a,x) memset(a,x,sizeof(a)) #define W(a) while(a) #define ll long long #define INF 0x3f3f3f3f #define EXP 1e-10 #define lowbit(x) (x&-x) using namespace std; int n[15],d[15]; int dp[100010]; int main(){ int cash,num; while(cin>>cash>>num){ MEM(n,0);MEM(d,0);MEM(dp,0); for(int i=1;i<=num;i++){ cin>>n[i]>>d[i]; } for(int i=1;i<=num;i++){ if(n[i]*d[i]>=cash){ //cout<<"hi"<<endl; for(int j=d[i];j<=cash;j++){ if(dp[j]<dp[j-d[i]]+d[i]){ dp[j]=dp[j-d[i]]+d[i]; } //cout<<j<<' '<<dp[j]<<endl; } } else{ int k=1,t=n[i]; while(t-k>=0){ t-=k; for(int j=cash;j>=k*d[i];j--){ if(dp[j]<dp[j-k*d[i]]+k*d[i]){ dp[j]=dp[j-k*d[i]]+k*d[i]; } } k*=2; } for(int j=cash;j>=t*d[i];j--){ if(dp[j]<dp[j-t*d[i]]+t*d[i]){ dp[j]=dp[j-t*d[i]]+t*d[i]; } } } //cout<<dp[cash]<<endl; } cout<<dp[cash]<<endl; } return 0; }