二维完全背包,第二层跟第三层的要顺序循环;(0-1背包逆序循环);状态可理解为,在背包属性为 {m(忍耐度), s(杀怪个数)} 里最多能得到的经验值,之前的背包牺牲体积,这个背包牺牲忍耐度跟个数
注意: 最后扫的时候 外层循环为忍耐度,内层循环为杀怪个数,因为题目要求出剩余忍耐度最大,没有约束杀怪个数,一旦找到经验加满的即为最优解;
状态转移方程为: f[j][l]=max(f[j][l],f[j-b[i]][l-1]+w[i]); a[i]表示杀死第i个怪所得的经验值,b[i]表示消耗的忍耐度
#include<stdio.h>
#include<string.h>
int f[100][100];
int max(int x,int y)
{
if(x<y)
return y;
else
return x;
}
int main()
{
int a[100],b[100];
int n,m,k,s;
int i,j,l,locate,flag;
while(scanf("%d%d%d%d",&n,&m,&k,&s)!=EOF)
{
memset(f,0,sizeof(f));
for(i=0;i<k;i++)
{
scanf("%d%d",&a[i],&b[i]);
}
for(i=0;i<k;i++)
{
for(j=b[i];j<=m;j++)//耐力
{
for(l=1;l<=s;l++)
{
f[j][l]=max(f[j][l],f[j-b[i]][l-1]+a[i]);
}
}
}
flag = 0;
for (i=0;i<=m;i++)
{
if(flag)
break;
for (j=0;j<=s;j++)
{
if (f[i][j]>=n)
{
locate = i;
flag = 1;
break;
}
}
}
if(flag)
printf("%d\n",m-locate);
else
printf("-1\n");
}
return 0;
}