题解:本题主要考查多重背包的二进制优化
简要题意:已知每种纸币的面值和数量,现在要凑某个数额的钱,最多可以凑多大的值(不能超过这个数额)。
1.多重背包:我们可以二进制优化多重背包,注意了这里的价值和体积一样
代码如下:
#include<iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
int money,n,k,a,b;
int dp[745765],num[3535346];
int main()
{
while(scanf("%d %d",&money,&n)!=EOF)
{
if(n==0){cout<<"0"<<endl;continue;}
k=0;
for(int i=1;i<=n;i++)
{
cin>>a>>b;
for(int j=1;j<=a;j<<=1)
{
num[++k]=j*b;
a-=j;
}
if(a>0)num[++k]=a*b;
}
for(int i=1;i<=k;i++)
for(int j=money;j>=num[i];j--)
dp[j]=max(dp[j],dp[j-num[i]]+num[i]);
cout<<dp[money]<<endl;
memset(dp,0,sizeof(dp));//注意数组清空
}
return 0;
}