游戏 DP

游戏 DP

【题意描述】

小喵喵喜欢玩 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]。

【输出格式】

一个整数,表示最多的金钱。

简单\(DP\)

设状态\(f[i][j]\)表示第\(i\)轮,现在攻击力为\(j\),用一个前缀和可以算出当前防御力为\(sum[i]-j\),按题意转移即可。

考试时,觉得初始攻击防御很烦,其实是读漏题了,就把所有怪物都减了1,小喵喵初始为0

#include <cstdio>
#include <algorithm>
#define MAX(A,B) ((A)>(B)?(A):(B))
#define ll long long
using namespace std;
inline int read(){
    char ch=getchar();int s=0;
    while(ch<'0'||ch>'9') ch=getchar();
    while(ch>='0'&&ch<='9') s=s*10+(ch^'0'), ch=getchar();
    return s;
}
#define MAXN 2019
int n;
bool hav[MAXN];
int atk[MAXN],def[MAXN],a[MAXN];
int sum[MAXN];
ll f[MAXN][MAXN];
int main(){
    n=read();
    for(int i=1;i<=n;++i){
        char opt=getchar();
        while(opt!='U'&&opt!='M') opt=getchar();
        sum[i]=sum[i-1];
        if(opt=='U'){
            ++sum[i];
        }else if(opt=='M'){
            hav[i]=1;
            a[i]=read(),atk[i]=read(),def[i]=read();
            --atk[i];
            --def[i];
        }else puts("ERROR");
    }
    for(register int i=1;i<=n;++i)
    for(register int j=0;j<=sum[i];++j){ // a
        int k=sum[i]-j;
        f[i][j]=f[i-1][j];
        if(!hav[i]){
            if(j>=1)
                f[i][j]=max(f[i-1][j-1], f[i][j]);
            f[i][j]=max(f[i-1][j], f[i][j]);
        }
        if(hav[i]&&j>=atk[i]&&k>=def[i]) f[i][j]+=(ll)a[i];
    }
    ll ans=0;
    for(register int j=0;j<=sum[n];++j) ans=max(ans, f[n][j]);
    printf("%lld", ans);
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/santiego/p/11824112.html