游戏(动态规划)

游戏
【题意描述】
小喵喵喜欢玩RPG游戏。在这款游戏中,玩家有两个属性,攻击和防御,现在小喵喵的攻击和防御都是1,接下来小喵喵会依次遇到n个事件。事件有两种。
1.小喵喵经过修炼,角色升级了,此时可以选择攻击+1或者防御+1.
2.小喵喵遇到了一个敌人,可以选择战斗或者逃跑。如果战斗,胜利后得到a[i]金钱。如果逃跑,则无事发生,但是以后也不能再回来打这个怪物了。
对于一场战斗来说,如果小喵喵的攻击力大于等于atk[i],防御力大于等于def[i],那么他可以无伤打败这只怪物,从而他选择打怪,否则他发现自己会受伤,从而选择逃跑。
现在小喵喵想知道,通过巧妙地选择升级时加的属性,他最多能够从这n个事件中获得多少金钱。
【输入格式】
第1行一个整数n。
第2~n+1行每行会有一个字符’U’或’M’,分别表示升级和怪物,如果是怪物,之后有空格隔开的三个整数a[i],atk[i],def[i]。
【输出格式】
一个整数,表示最多的金钱。
【样例输入输出】
5
U
U
M 2 1 2
M 5 2 1
M 3 1 3 7
【样例解释】
小喵喵可以选择分别增加一次攻击和防御,从而可以打3号和4号怪物。总的金钱是2+5=7.

【数据范围】
对于20%的数据,n<=10
对于另外20%的数据,所有怪物的def[i]为1.
对于另外30%的数据,n<=100
对于所有的数据,n<=2000,1<=atk[i],def[i]<=n,a[i]<=109.

 

本题可以使用动态规划求解。

此题需要一开始看要考虑两种情况升级和打怪,我们要求的是最大的钱数,每次升级衍生两种可能,打怪与不打取决于你点的能力值,所以总的来说结果是取决于你升级后的点的技能点,本题也就是求最佳的升级法。

创建一个二维数组dp用来保存所有的升级方式的收益,开始从攻防各1,1开始向外递推,dp[1][1]->dp[1][2],dp[2][1];在没有遇到怪时升级后的最大收益和未升级前相同,遇到怪后更新所有可以战胜的怪的属性组。

#include <bits/stdc++.h>
using namespace std;
long long dp[2000][2000], maxN;
int main() {
    int n, utimes = 2, a, atk, def;
    char c;
    cin >> n;
    while (n--) {
        cin >> c;
        if (c == 'U') {
            ++utimes;
            for (int i = 1; i < utimes; ++i)
                //升级后的收益为 先前两种路线中最大的收益(加攻/加防)
                dp[i][utimes-i] = max(dp[i-1][utimes-i], dp[i][utimes-i-1]);
        }else {
            cin >> a >> atk >> def;
            for (int i = atk; i < utimes; ++i)//遍历可以打怪的属性
                if (utimes-i >= def) dp[i][utimes-i] += a, maxN = max(maxN, dp[i][utimes-i]);//更新最大值
        }
    }
    cout << maxN << endl;
    return 0;
}

utimes 为可分配的点数。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值