我的轮数设置的是0~n-1,所以设置了初始状态,枚举的k是截至上一轮结束换牌的次数,而dp存的是截至当前轮结束换牌的次数,样例过了,然后提交错了一个#8,想了半天不知道哪里错了。
源代码(90):
#include <bits/stdc++.h>
using namespace std;
int n, i, j, k, now;
long ans;
long A[1010], B[1010], C[1010], dp[1010][3][1010]; // dp[i][j][k]=第i轮出牌为j,截至这一轮结束已经换了k次牌时的最大分数
int main()
{
cin >> n;
for (i = 0; i < n; i++)
cin >> A[i];
for (i = 1; i < n; i++)
cin >> B[i];
for (i = 0; i < n; i++)
cin >> C[i];
dp[0][(C[0] + 1) % 3][0] = A[0] * 2;
dp[0][C[0]][0] = A[0];
for (i = 1; i < n; i++) // 第i轮
for (j = 0; j < 3; j++) // 这一轮出牌为j
for (k = 0; k < i; k++) // 截至上一轮已经换了k次牌
{
if (j == (C[i] + 1) % 3)
{
dp[i][j][k] = max(dp[i][j][k], dp[i - 1][j][k] + A[i] * 2);
now = (j + 1) % 3;
dp[i][j][k + 1] = max(dp[i][j][k + 1], dp[i - 1][now][k] + A[i] * 2 - B[k + 1]);
now = (now + 1) % 3;
dp[i][j][k + 1] = max(dp[i][j][k + 1], dp[i - 1][now][k] + A[i] * 2 - B[k + 1]);
}
else if (j == C[i])
{
dp[i][j][k] = max(dp[i][j][k], dp[i - 1][j][k] + A[i]);
now = (j + 1) % 3;
dp[i][j][k + 1] = max(dp[i][j][k + 1], dp[i - 1][now][k] + A[i] - B[k + 1]);
now = (now + 1) % 3;
dp[i][j][k + 1] = max(dp[i][j][k + 1], dp[i - 1][now][k] + A[i] - B[k + 1]);
}
else
{
dp[i][j][k] = max(dp[i][j][k], dp[i - 1][j][k]);
now = (j + 1) % 3;
dp[i][j][k + 1] = max(dp[i][j][k + 1], dp[i - 1][now][k] - B[k + 1]);
now = (now + 1) % 3;
dp[i][j][k + 1] = max(dp[i][j][k + 1], dp[i - 1][now][k] - B[k + 1]);
}
}
for (j = 0; j < 3; j++)
for (k = 0; k < n; k++)
ans = max(ans, dp[n - 1][j][k]);
cout << ans << endl;
return 0;
}