ゲームDP
[問題の説明意味は、
RPGのゲームをプレイするような小さなニャー。このゲームでは、プレイヤーは2つの属性攻撃と防御を持っており、今の小さなニャーの攻撃と防御が1あり、次の出会いは小さなニャーn個のイベントが続きます。2つのイベントがあります。
1.小型の練習後ニャー、アップグレードの役割、そして、あなたは攻撃に選択することができます
+1
か防衛+1
。2.小さなニャーニャーは敵に遭遇し、あなたは、戦うか逃げるように選択することができます。勝利後の戦いは、[i]はお金を得るためにした場合。あなたは離れて実行している場合は、関係なく起こりませんが、もはやこの怪物の後に遊びに戻って来ることができます。
戦いのために、より小さなニャーニャー攻撃の場合またはに等しい
atk[i]
、以上の防衛def[i]
彼はDaguaiに選んだので、彼は、モンスターを倒すために傷つけることができない、または彼は彼自身が負傷者を見つけるため、脱出することを選択します。今、小さなニャーは巧みに、追加のアップグレードの属性を選択することで、彼がここまででき、知りたい\(N \)どのくらいのお金を一つのイベント。
[入力形式]
最初の行の整数\(N- \) 。
2〜N + 1ラインのそれぞれ文字「U」または「M」を有し、それぞれ、モンスターをアップグレードするには、モンスターであれば、3つの空間は、[i]は整数[i]は、ATKによって分離された後、 DEF [i]を。
[出力形式]
最もお金を表す整数。
シンプルな\(DP \)
リセット状態\(F [i]が[J ] \) を表す(I \)\ラウンド、それが攻撃することです(\ J)\、および現在の防衛の接頭辞を用いて計算することができる[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;
}