动态规划问题--“游戏王”,将每个游戏标上一个成就值,同时对每个游戏都估算一个通关所需要的天数,他计划在未来X天内让自己玩游戏的成就达到最大

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]);
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值