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;
}