import java.util.Scanner;
/*
题目描述:
有许多程序员都热爱玩游戏,而小J自称为游戏王,曾玩过几百种游戏,几乎所有能玩到的游戏大作都玩遍了。
随着时间的推移,他发觉已经没有游戏可以让他玩了!于是他想改玩一些古老的游戏,以成为真正的“游戏王”。
他希望在接下来的一段时间内将过去出的游戏全部玩一遍,但是毕竟时间有限,因此他感到很苦恼。于是他想到一个计划
,他先将每个游戏标上一个成就值,同时对每个游戏都估算一个通关所需要的天数,他计划在未来X天内让自己玩游戏的成就达到最大
,那么他应该怎么做计划呢?(假设每个游戏最多只计划玩一遍,而且每个游戏必须玩完通关才能取得成就值,且通关每个游戏最小时间单位是1天)
输入描述
第一行输入两个整数N和X,中间用空格隔开,其中N表示游戏的数目N(1<=N<=10),X表示计划玩游戏的总时间天数 (1<=X<=1000)。
第二行输入第1个游戏的成就值A1(0<=A1<=10000) 和 通关所需要花费时间B1天 (1<=Bi<=500) 中间用空格隔开。
第N+1行输入第N游戏的成就值An(0<=An<=10000) 和 通关所需要花费时间Bn天(1<=Bn<=500) 中间用空格隔开
输出描述
可以达到成就之和的最大值。
样例输入
2 2
10 1
20 2
样例输出
20
提示
输入样例二:
3 4
10 2
18 3
10 2
输出样例二:
20
*/
public class Q2 {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
//第一行输入两个整数N和X,中间用空格隔开,其中N表示游戏的数目N(1<=N<=10),X表示计划玩游戏的总时间天数 (1<=X<=1000)。
int n = in.nextInt();
int x = in.nextInt();
//第二行输入第1个游戏的成就值A1(0<=A1<=10000) 和 通关所需要花费时间B1天 (1<=Bi<=500) 中间用空格隔开。
//第N+1行输入第N游戏的成就值An(0<=An<=10000) 和 通关所需要花费时间Bn天(1<=Bn<=500) 中间用空格隔开
int [] val = new int[n];
int [] days = new int[n];
for (int i = 0; i < n; i ++) {
val[i] = in.nextInt();
days[i] = in.nextInt();
}
in.close();
//动态规划
//dp[i][j],表示最大天数为j,玩前i个游戏的最大成就值
//状态转移方程
//dp[i][j] = max (dp[i - 1][j], dp[i - 1][ j - days[i - 1] ] + val[i - 1])
int [][] dp = new int[n + 1][x + 1];
//容量为 0 的时候 最大成就怎么都为0
for (int i = 1; i <= n; i++) {
dp[i][0] = 0;
}
//选择前0个游戏的时候 最大成就也是怎么都为0
for (int j = 0; j <= x; j++) {
dp[0][j] = 0;
}
//这一步java默认初始化为0,不处理
for (int i = 1; i <= n; i ++) {
for (int j = x; j >= 0; j --) {
if (j < days[i - 1]) {
dp[i][j] = dp[i - 1][j];
} else {
dp[i][j] = Math.max(dp[i - 1][j], dp[i - 1][j - days[i - 1]] + val[i - 1]);
}
}
}
System.out.println(dp[n][x]);
}
}
动态规划问题--“游戏王”,将每个游戏标上一个成就值,同时对每个游戏都估算一个通关所需要的天数,他计划在未来X天内让自己玩游戏的成就达到最大
最新推荐文章于 2021-02-13 02:07:29 发布