题目链接:
http://codeforces.com/gym/102056/problem/I
题意:
人物有l两个属性分别是$A,D$
每个回合人物$Apm D$
每个回合有三个选择分别是:
1,对怪物造成$a_i+A$的伤害
2,$Apm c_i$
3,$Dpm b_i$
求n回合后对怪物造成的最大伤害
数据范围:
$1 le n le 100$
$1le a_i, b_i, c_i le 10^9$
分析:
虽然比赛的时候想到了用DP来做也想到了逆序处理,但是一直不知道怎么定义状态。赛后看到题解,瞬间明白。
定义$DP[i][j][k]$,代表在$i$回合,攻击了$j$次,攻击的回合累加是$k$
注意:long long类型的数组不要大于$3 imes 10^7$,会超空间
ac代码:
#include<bits/stdc++.h> #define ll long long using namespace std; const int maxn=110; const int maxm=10000+10; int a[maxn],b[maxn],c[maxn]; ll dp[2][maxn][maxm]; int main() { int T,n; scanf("%d",&T); while(T--) { scanf("%d",&n); for(int i=n;i>=1;i--) scanf("%d %d %d",&a[i],&b[i],&c[i]); for(int j=0;j<=n;j++)for(int k=0;k<=n*n;k++)dp[1][j][k]=-1e18; dp[1][1][1]=a[1]; for(int i=2;i<=n;i++) { for(int j=0;j<=n;j++)for(int k=0;k<=n*n;k++) dp[0][j][k]=dp[1][j][k],dp[1][j][k]=-1e18; for(int j=0;j+1<=n;j++) for(int k=0;k+i<=n*n;k++) dp[1][j+1][k+i]=max(dp[1][j+1][k+i],dp[0][j][k]+a[i]); for(int j=0;j<=n;j++) for(int k=0;k<=n*n;k++) dp[1][j][k]=max(dp[1][j][k],dp[0][j][k]+(ll)c[i]*j), dp[1][j][k]=max(dp[1][j][k],(ll)(i*j-k)*b[i]+dp[0][j][k]); } ll ans=0; for(int i=0;i<=n;i++) for(int j=0;j<=n*n;j++) ans=max(dp[1][i][j],ans); printf("%lld ",ans); } return 0; }