Problem:
给定总钱数
n
n
n,钞票数
m
m
m,以及每张钞票的张数
c
i
c_i
ci和面额
w
i
w_i
wi,求能组成的面额小于等于
n
n
n的最大面额。
Solution:
多重背包,二进制分组。
#include <stdio.h>
#include <string.h>
#define max(a,b) ((a)>(b)?(a):(b))
int n,m,c[1001],w[1001],f[100001];
int main()
{
while(~scanf("%d",&n))
{
memset(f,0,sizeof(f));
scanf("%d",&m);
for(int i=1; i<=m; i++)
scanf("%d%d",&c[i],&w[i]);
for(int i=1; i<=m; i++)
{
int k, t;
k = 1;
t = c[i];
while(t > k)
{
for(int j = n; j >= w[i]*k; j--)
f[j] = max(f[j],f[j-w[i]*k]+w[i]*k);
t -= k;
k *= 2;
}
for(int j = n; j >= w[i]*t; j--)
f[j] = max(f[j],f[j-w[i]*t]+w[i]*t);
}
printf("%d\n",f[n]);
}
return 0;
}