题解:P10111 [GESP202312 七级] 纸牌游戏
题目大意
给出三个序列:\(a\) ,\(b\) ,\(c\)
分别表示:分数,罚分以及小杨从第 \(1\) 轮至第 \(𝑁\) 轮出的牌,你从第 \(2\) 轮开始,要么继续出上一轮出的牌,要么记一次“换牌”。游戏结束时,你换了 \(t\) 次牌,就要额外扣 \(b_1+…+b_t\) 分。
请计算出你最多能获得多少分。
解题思路
我们使用动态规划来解决。
状态:
\(f_{i,j,k}\)表示进行到第 \(i\) 轮,换了 \(j\) 次牌,牌为 \(k\) 的最大得分。
Code
#include <bits/stdc++.h>
using namespace std;
int n;
int a[1001], b[1001], c[1001];
int f[1001][1001][5]; // 进行到第i轮,换了j次牌,牌k的最大得分
int ans;
int main()
{
cin >> n;
for (int i = 1; i <= n; i++)
cin >> a[i];
for (int i = 1; i < n; i++)
cin >> b[i];
for (int i = 1; i <= n; i++)
cin >> c[i];
for (int i = 1; i <= n; i++)
{
for (int j = 0; j < i; j++) // 枚举本轮换牌次数(到第i轮最多换了i-1次牌)
{
for (int k = 0; k < 3; k++)
{
int add = 0, hp = INT_MIN;
if ((c[i] + 1) % 3 == k)
add = a[i] * 2;
if (k == c[i])
add = a[i];
if (j < i - 1 || i == 1)
hp = max(hp, f[i - 1][j][k]);
if (j > 0)
hp = max(hp, max(f[i - 1][j - 1][(k + 1) % 3], f[i - 1][j - 1][(k + 2) % 3]) - b[j]);
f[i][j][k] = hp + add;
}
}
}
for (int i = 0; i < n; i++)
ans = max({ans, f[n][i][0], f[n][i][1], f[n][i][2]});
cout << ans;
return 0;
}

浙公网安备 33010602011771号