背包问题,建议先看看背包九讲,然后这道题就能水之。。。
这是我整理背包九讲里的模板,有基础的可以看看,大牛就不要来鄙视我这个小菜了。。。
//01背包
procedure ZeroOnePack(cost,weight)
for v=V..cost
f[v]=max{f[v],f[v-cost]+weight}
for i=1..N
ZeroOnePack(c[i],w[i]);
//完全背包
procedure CompletePack(cost,weight)
for v=cost..V
f[v]=max{f[v],f[v-c[i]]+w[i]}
for i=1..N
CompletePack(cost,weight);
//多重背包
procedure MultiplePack(cost,weight,amount)
if cost*amount>=V
CompletePack(cost,weight)
return
integer k=1
while k<amount
ZeroOnePack(k*cost,k*weight)
amount=amount-k
k=k*2
ZeroOnePack(amount*cost,amount*weight)
for i=1..N
MultiplePack(cost,weight,amount);
#include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<cstring>
#define MAX 100111
using namespace std;
int cash,N;
int n[20],d[20];
int f[MAX];
void ZeroOnePack(int cost,int weight)
{
for(int v=cash;v>=cost;v--)
f[v]=max(f[v],f[v-cost]+weight);
//cout<<f[cash]<<endl;
}
void CompletePack(int cost,int weight)
{
for(int v=cost;v<=cash;v++)
f[v]=max(f[v],f[v-cost]+weight);
//cout<<f[cash]<<endl;
}
void MultiplePack(int cost,int weight,int amount)
{
if (cost*amount>=cash)
{
CompletePack(cost,weight);
return ;
}
int k=1;
while (k<amount)
{
ZeroOnePack(k*cost,k*weight);
amount=amount-k;
k=k*2;
}
ZeroOnePack(amount*cost,amount*weight);
}
int main()
{
int i;
while(cin>>cash>>N)
{
for(i=1;i<=N;i++)
cin>>n[i]>>d[i];
memset(f,0,sizeof(f));
for(i=1;i<=N;i++)
{
MultiplePack(d[i],d[i],n[i]);
}
for(i=cash;i>=0;i--)
if(f[i]==i)
{cout<<f[i]<<endl;break;}
}
}