Misunderstood … Missing【18EC】

Misunderstood … Missing

题意

初始攻击值 (A = 0) ,成长值 (D = 0) , 每过一回合都会有 (A = A + D)

(n) 回合,每回合有三种选择

①. 造成 (A+a[i]) 的伤害

②. 提升 (b[i]) 的成长值

③. 提升 (c[i]) 的攻击值

给定 (n, a[],b[],c[])

求造成的最大伤害

由于二三操作对后面的影响是可以进行计算的

在设状态的时候可以只考虑一操作的状态从后往前 (dp)

f[pos][num][sum] 表示

(pos) 处开始到 (n) ,使用了 (num) 次操作 (1) , 并且这些位置的和是 (sum)

可以利用 (num)(sum) 从后往前对二三操作直接计算贡献值

#include<bits/stdc++.h>
using namespace std;

typedef long long ll;
ll f[2][101][5055];

ll a[110], b[110], c[110];
ll T, n;
int main() {
	scanf("%lld", &T);
	while (T--) {
		scanf("%lld", &n);
		for (int i = 1; i <= n; i++) {
			scanf("%lld%lld%lld", a + i, b + i, c + i);
		}
		memset(f, -0x3f, sizeof f);
		int now = 0;
		f[0][1][n] = a[n];
		f[0][0][0] = 0;
		for (ll i = n - 1ll; i >= 1; i--) {
			now ^= 1; int pre = now ^ 1;
			for (ll j = 0; j <= n - i; j++) {
				for (ll k = 0; k <= (n - i) * (n + i + 1) / 2; k++) {
					f[now][j + 1][k + i] = max(f[now][j + 1][k + i], f[pre][j][k] + a[i]);
					f[now][j][k] = max(f[now][j][k], f[pre][j][k] + (k - j * i) * b[i]);
					f[now][j][k] = max(f[now][j][k], f[pre][j][k] + c[i] * j);
				}
			}
		}
		ll ans = 0;
		for (int i = 0; i <= n; i++) {
			for (int j = 0; j <= (n + 1) * n / 2; j++) {
				ans = max(ans, f[now][i][j]);
			}
		}
		printf("%lld
", ans);
	}
}
原文地址:https://www.cnblogs.com/sduwh/p/14064093.html