题解: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;
}
posted @ 2024-08-15 22:31  ACyming  阅读(177)  评论(0)    收藏  举报