题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2159
思路:dp[j][l]表示消耗了j忍耐度,杀了l个怪后获得的经验值;最后只要对dp扫一遍,找出是否有大于等于n的值,如果有,这保留此时的消耗的忍耐值;否则,输出-1;
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<iostream> 2 const int N=110; 3 using namespace std; 4 struct Node{ 5 int value,cost; 6 }node[N]; 7 int dp[N][N]; 8 9 int main(){ 10 int n,m,k,s; 11 while(~scanf("%d%d%d%d",&n,&m,&k,&s)){ 12 for(int i=0;i<k;i++){ 13 scanf("%d%d",&node[i].value,&node[i].cost); 14 } 15 memset(dp,0,sizeof(dp)); 16 for(int i=0;i<k;i++){ 17 for(int j=node[i].cost;j<=m;j++){ 18 //限定杀怪的个数 19 for(int l=1;l<=s;l++){ 20 dp[j][l]=max(dp[j][l],dp[j-node[i].cost][l-1]+node[i].value); 21 } 22 } 23 } 24 int flag=false,k; 25 for(int j=0;j<=m;j++){ 26 if(flag)break; 27 for(int l=1;l<=s;l++){ 28 if(dp[j][l]>=n){ 29 flag=true; 30 k=j; 31 break; 32 } 33 } 34 } 35 if(flag){ 36 printf("%d\n",m-k); 37 }else 38 printf("%d\n",-1); 39 } 40 return 0; 41 }