给你一个cash,n种钱,每种钱的数量及价值,问最大接近cash凑成多少。
就是多重背包。
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
int cash,n,numb[20],value[20],dp[1000000];
void complete(int cost){
for(int j=cost;j<=cash;j++){
if(dp[j-cost]){
dp[j]=1;
}
}
}
void zeroone(int cost){
for(int j=cash;j>=cost;j--){
if(dp[j-cost]){
dp[j]=1;
}
}
}
int main(){
while(scanf("%d",&cash)!=EOF){
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%d%d",&numb[i],&value[i]);
}
for(int i=0;i<=cash;i++)
dp[i]=0;
dp[0]=1;
for(int i=1;i<=n;i++){
if(numb[i]){
if(numb[i]*value[i]>=cash){
complete(value[i]);
}
else{
int ki=1,amount=numb[i];
while(ki<amount){
zeroone(value[i]*ki);
amount-=ki;
ki*=2;
}
zeroone(value[i]*amount);
}
}
}
int j=cash;
while(dp[j]==0&&j>0){
j--;
}
printf("%d\n",j);
}
return 0;
}