题目链接:http://codeforces.com/gym/102056/problem/I
题意: 每次有三种选择做n次,问总共打了多少伤害
每次攻击力A都会先增加D的成长值。
每回合三种操作
1. 打出伤害A+a[i]
2. D添加b[i]
3. A永久添加c[i]
明显的dp题,就是有点难d它。。。。
需要倒着递推
主要状态有 从i开始攻击的轮数j, 所有攻击的轮数之和z这两大状态,
ac代码:
#include <cstdio>
#include <cstring>
#include <vector>
#include <iterator>
#include <set>
#include <iostream>
#include <vector>
#include <cmath>
#include <algorithm>
using namespace std;
const double esp = 1e-6;
const int mx = 6e3+100;
typedef long long ll;
ll dp[2][205][mx], a[205][5];
///dp[i][j][k] i表示第几轮,j表示打几场k表示所有打的轮数之和。。。
int main() {
int T, n;
scanf("%d", &T);
while (T--) {
scanf("%d", &n);
memset(dp, 0, sizeof(dp));
for (int i = 1; i <= n; ++i) {
for (int j = 1; j <= 3; ++j) {
scanf("%lld", &a[i][j]);
}
}
int cur = 0;
dp[cur^1][1][n] = a[n][1];
ll ma = a[n][1];
for (int i = n-1; i >= 1; --i) {
int st, ed = 0;
for (int j = 1; j+i <= n; ++j) {
st =(i+i+j)*(j-1)/2+n , ed = (n+n-j+1)*j/2;///上下界
for (int z = st; z <= ed; ++z) {
dp[cur][j+1][z+i] = max(dp[cur][j+1][z+i], dp[cur^1][j][z]+a[i][1]);
dp[cur][j][z] = max(dp[cur][j][z], dp[cur^1][j][z]+a[i][2]*(z-j*i));
dp[cur][j][z] = max(dp[cur][j][z], dp[cur^1][j][z]+a[i][3]*j);
}
}
cur ^= 1;
}
for (int j = 1; j <= n; ++j)
for (int i = 0; i <= 5500; ++i) ma = max(ma, dp[cur^1][j][i]);
printf("%lld\n", ma);
}
return 0;
}