TAG
- 算法 − 【 D P 】、思维 − 【 3 维退化成 2 维】 算法 - 【DP】、思维 - 【3维退化成2维】 算法−【DP】、思维−【3维退化成2维】时间复杂度
- O ( N ∗ M 2 ) O(N \ast M^2) O(N∗M2)
//
#include <bits/stdc++.h>
using namespace std;
// #define int long long
const int N = 1005;
const int M = 200; // ??
int dp[N][3][M+5][M+5]; // 【共 i 天】【未训练的技能编号为 j】【j + 1 号技能训练 x 天】【j + 2 号技能训练 y 天】
int in[N][3];
inline void max(int& a, int b) {
a = std::max(a, b);
}
void solve() {
// ai_max = 1e4
// 1e4 <= n * (1 + n) / 2
int n;
scanf("%d", &n);
for (int i = 1; i <= n; i++) {
for (int j = 0; j < 3; j++) {
scanf("%d", &in[i][j]);
}
}
// TLE
// memset(dp, 0, sizeof(dp));
for (int i = 0; i <= n; i++) {
for (int j = 0; j < 3; j++) {
for (int x = 0; x <= M; x++) {
for (int y = 0; y <= M; y++) {
dp[i][j][x][y] = 0;
}
}
}
}
for (int i = 0; i < n; i++) {
for (int j = 0; j < 3; j++) {
// 把控天数的越界问题
for (int x = 0; x <= min(M, i); x++) {
for (int y = 0; y <= min(M, i); y++) {
// 【tx: x 的下一天】【ty: y 的下一天】
int tx = x ? x + 1 : 0, ty = y ? y + 1 : 0;
int now = dp[i][j][x][y];
// 从状态 now 往 3 个方向扩展
// 1 tx ty
// tx ty 1
// ty 1 tx
max(dp[i + 1][j][tx][ty], now - tx - ty + in[i + 1][j]);
max(dp[i + 1][(j + 1) % 3][ty][1], now - ty - 1 + in[i + 1][(j + 1) % 3]);
max(dp[i + 1][(j + 2) % 3][1][tx], now - 1 - tx + in[i + 1][(j + 2) % 3]);
}
}
}
}
int ans = 0;
for (int j = 0; j < 3; j++) {
for (int x = 0; x <= M; x++) {
for (int y = 0; y <= M; y++) {
max(ans, dp[n][j][x][y]);
}
}
}
printf("%d\n", ans);
}
signed main() {
int t = 1;
scanf("%d", &t);
while (t--) solve();
}
实现细节
- `
参考示意图
-
`
参考链接
作者 | 乐意奥AI