多重背包问题,直接模板就可以了
题意:给出chash,给n种面额和每种面额的张数,尽可能组成与chash最近的面额
#include <iostream>
#include<stdio.h>
#include<string>
#include<cstring>
#include<algorithm>
#include<cmath>
#define N 520009
using namespace std;
int vol[N];
int val[N];
int cash;
int dp[N];
void zeroonebag(int c,int w)
{
for(int i=cash;i>=c;i--)
dp[i]=max(dp[i],dp[i-c]+w);
}
void combag(int c,int w)
{
for(int i=c;i<=cash;i++)
dp[i]=max(dp[i],dp[i-c]+w);
}
void mulbag(int c,int w,int p)
{
if(c*p>cash)
combag(c,w);
else{
int k=1;
while(k<p)
{
zeroonebag(c*k,w*k);
p-=k;
k<<=1;
}
zeroonebag(c*p,w*p);
}
}
int main()
{
int n;
while(~scanf("%d%d",&cash,&n))
{
memset(dp,0,sizeof dp);
for(int i=1;i<=n;i++)
scanf("%d%d",&vol[i],&val[i]);
for(int i=1;i<=n;i++)
{
mulbag(val[i],val[i],vol[i]);
}
printf("%d\n",dp[cash]);
}
return 0;
}