hdu 2159 FATE(DP)

题意:

小余玩游戏,离最后一级还需n的经验值,但是他已经很厌烦了,还剩下m的忍耐度。每杀一只怪小余会得到相应的经验,同时减掉相应的忍耐度。

当忍耐度降到0或者0以下时,小余就不会再玩这个游戏。小余还说他最多杀s只怪。

求小余升完最后一级能保留的最大忍耐度。如果无法升完最后一级则输出-1。

输入:

n, m, k, s  分别表示:还需要的经验值、保留的忍耐度、怪的种数、最多的杀怪数

接下来k行每行两个数a,b。分别表示杀一只当前各类的怪会得到的经验值和会减掉的忍耐度。(每种怪都有无数个)

思路:

额,,背包

本来是用背包求出减掉的最少忍耐度,可是写完以后发现,,经验值n不能作为背包容量,因为获得的经验值可能会大于n,是不确定的。

改变思路,发现忍耐度是不能为负的(即不会被超过),所以喽,求某个忍耐度下能获得的最大经验值,判断其是否大于等于n即可~

看代码~

代码:

struct node{
    int exp, ren;
}
mons[105];



int dp1[105][105];


int main(){
    int n,m,k,s;
    while(cin>>n>>m>>k>>s){
        rep(i,1,k){
            cin>>mons[i].exp>>mons[i].ren;
        }

        mem(dp1,0);

        rep(i,1,k){ //怪兽种类
            rep(j,mons[i].ren,m){ //最大的忍耐度
                rep(k,1,s){ //最多杀怪的只数
                    dp1[j][k] = max( dp1[j][k],dp1[j-mons[i].ren][k-1]+mons[i].exp );
                }
            }
        }
        if(dp1[m][s]<n){
            puts("-1");
        }else{
            int ans = inf;
            rep(i,0,m){
                rep(j,1,s){
                    if(dp1[i][j]>=n && i<ans) ans=i;
                }
            }
            cout<<m-ans<<endl;
        }
    }


    return 0;
}
原文地址:https://www.cnblogs.com/fish7/p/4229982.html