这个题我一开始直接把物品数量拆成一个一个的,然后直接DP,T了。
于是就不在懒了...
其实也没有复杂多少
把物品拆成1+2+4+...+2^k+(N-2^(k+1)) 保证和是物品数量就好了,然后DP
#include<stdio.h>
#include<string.h>
long long cash[100001];
long long val[102];
int main()
{
int i,j,k;
int n,most;
int count;
int amount;
while(scanf("%d%d",&most,&n)!=EOF)
{
memset(cash,0,sizeof(cash));
count=0;
for(i=0;i<n;i++)
{
scanf("%d%d",&amount,&j);
k=1;
while(amount-k>=0)//这个地方把K件物品拆成1,2,4,8....2^k amount-2^(k+1)个
{
val[count++]=j*k;
amount-=k;
k*=2;
}
if(amount!=0)
val[count++]=amount*j;
}
cash[0]=1;
for(i=0;i<count;i++)//01背包
{
for(j=most;j>0;j--)
{
if((j-val[i]>=0))
{
if(cash[j-val[i]])
cash[j]=1;
}
}
}
i=most;
while(!cash[i])
i--;
printf("%d\n",i);
}
}