虽然是个入门的DP,但是实际消耗了整整一晚上+一个白天。
DP的内容,总是代码少,理解难。
package info.frady.luogu;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.StringTokenizer;
/**
假设你还有i瓶药,你的某个朋友要yao瓶药才能怼死。
当yao<=i时
如果你不怼,那你还剩i瓶药,经验加(失败经验)
如果你怼,那你还剩i-x瓶药,经验加(获胜经验)
当 yao >i时 我们没有没有办法,只能失败,参照上方不怼时(当然是不会用药打必输局的);
现在每个人输入一个lose(失败经验) win(获胜经验)yao(打死需要的药)
从0轮到x-yao(可以选择怼或不怼)
for(int l=0;l<=x-yao;l++)
f[l]=max(f[l]+lose,f[l+yao]+win);//f[l]表示还有多少药, f[l]+lose表示本轮认输,药就没有消耗 f[l+yao]指的是上次剩余l+yao药的最好成绩
从x-yao+1轮到x(怼不起)x是我剩余的药,x-yao+1是我刚好干不过的分界线,之后的都干不过,只能不喝药直接认输
for(int l=x-yao+1;l<=x;l++)
f[l]+=lose;//不用药,用药就是浪费。
最后输出发f[0]*5,药都用完能拿多少经验,记住5倍经验日!!
*/
public class P1802 {
public static void main(String[] args) throws Exception{
BufferedReader reader=new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st=new StringTokenizer(reader.readLine());
int N=Integer.parseInt(st.nextToken());//对手的个数
int X=Integer.parseInt(st.nextToken());//药水的个数
long fn[]=new long[X+1];//这个地方保存的是,剩余*个药水,能拿到的最多经验
for (int i = 0; i <N ; i++) {
st=new StringTokenizer(reader.readLine());
int lose=Integer.parseInt(st.nextToken());
int win=Integer.parseInt(st.nextToken());
int drug=Integer.parseInt(st.nextToken());
for(int l=0;l<=X-drug;l++) {//这个区间,药水是可以K掉当前对手的,可以选择一样, 要么认输,药水不变化,拿认输的经验 要么喝药,药水变化,拿胜利的经验
fn[l] = Math.max(fn[l] + lose, fn[l + drug] + win);
}
for(int l=X-drug+1;l<=X;l++) {//这个区间,你的药水不够,直接认输(认输了肯定不喝药的)
fn[l] += lose;
}
}
System.out.println(fn[0]*5);//输出剩余0个药水的经验数*5
reader.close();
}
}