题意:
小余玩游戏,离最后一级还需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; }