该题只是在完全背包基础之上加了一个条件,就是只能杀s个怪,那么我们就对每次记录每次在该忍耐点所杀的怪,如果所杀的怪大于所给的数目,那么我们就不更换经验值。怎样计算所剩的忍耐点,我们知道每一个忍耐点都是所杀怪所得到的经验值最大,那么我们只要对f进行遍历一遍,如果经验值大于等于所给的经验值,代表在该忍耐点已经可以获得了升级。
#include<stdio.h>
#include<stdlib.h>
int DP( int add[],int reduce[], int n, int m, int k,int s )
{
int f[124]={0},hash[124]={0},;
for( int i=1; i<=k; i++ )
{
for( int j=0; j<=m; j++ )
if( j>=reduce[i]&&f[j]<(f[j-reduce[i]]+add[i])&&hash[j-reduce[i]]+1<=s )
{
f[j]=f[j-reduce[i]]+add[i] ;
hash[j]=hash[j-reduce[i]]+1;
}
}
for( int j=0;j<=m; j++ )
{
if( f[j]>=n )
return m-j;
}
return -1;
}
int main()
{
int n,m,k,s,add[124],reduce[124];
while( scanf( "%d%d%d%d",&n,&m,&k,&s )!=EOF )
{
for( int i=1;i<=k; i++ )
scanf( "%d%d",&add[i],&reduce[i] );
printf( "%d\n",DP( add, reduce,n,m,k,s ) );
}
return 0;
}