HDU 2159 FATE
该题只是在完全背包基础之上加了一个条件,就是只能杀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; }