动态规划,多重背包
题目大意:
有各种不同面值的货币,每种面值的货币有不同的数量,请找出利用这些货币可以凑成的最接近且小于等于给定的数字cash的金额。
// Time 79ms; Memory 640K
#include<iostream>
using namespace std;
int v,f[100010];
void zeroone_pack(int c) //01背包
{
for(int i=v;i>=c;i--) if(!f[i])
{
f[i]=f[i-c];
}
}
void complete_pack(int c) //完全背包
{
for(int i=c;i<=v;i++) if(!f[i])
{
f[i]=f[i-c];
}
}
void multiple_pack(int c,int n) //多重背包
{
if(n>=v)
{
complete_pack(c);return;
}
int k=1;
while(k<n)
{
zeroone_pack(c*k);
n-=k;
k*=2;
}
zeroone_pack(c*n);
}
int main()
{
int i,n,c,m;
while(cin>>v>>m)
{
memset(f,0,sizeof(f));
f[0]=1;
for(i=0;i<m;i++)
{
cin>>n>>c;
multiple_pack(c,n);
}
for(i=v;i>=0;i--) if(f[i])
{
cout<<i<<endl;break;
}
}
return 0;
}