《P10111 [GESP202312 七级] 纸牌游戏》
题目背景
对应的选择、判断题:试题 - GESP 202312 C++ 七级 - 洛谷有题
题目描述
你和小杨在玩一个纸牌游戏。
你和小杨各有 3 张牌,分别是 0、1、2。你们要进行 N 轮游戏,每轮游戏双方都要出一张牌,并按 1 战胜 0,2 战胜 1,0 战胜 2 的规则决出胜负。第 i 轮的胜者可以获得 2×ai 分,败者不得分,如果双方出牌相同,则算平局,二人都可获得 ai 分 (i=1,2,⋯,N)。
玩了一会后,你们觉得这样太过于单调,于是双方给自己制定了不同的新规则。小杨会在整局游戏开始前确定自己全部 n 轮的出牌,并将他的全部计划告诉你;而你从第 2 轮开始,要么继续出上一轮出的牌,要么记一次“换牌”。游戏结束时,你换了 t 次牌,就要额外扣 b1+⋯+bt 分。
请计算出你最多能获得多少分。
输入格式
第一行一个整数 N,表示游戏轮数。
第二行 N 个用单个空格隔开的非负整数 a1,⋯,aN,意义见题目描述。
第三行 N−1 个用单个空格隔开的非负整数 b1,⋯,bN−1,表示换牌的罚分,具体含义见题目描述。由于游戏进行 N 轮,所以你至多可以换 N−1 次牌。
第四行 N 个用单个空格隔开的整数 c1,⋯,cN,依次表示小杨从第 1 轮至第 N 轮出的牌。保证 ci∈{0,1,2}。
输出格式
一行一个整数,表示你最多获得的分数。
输入输出样例
输入 #1复制
4 1 2 10 100 1 100 1 1 1 2 0
输出 #1复制
219
输入 #2复制
6 3 7 2 8 9 4 1 3 9 27 81 0 1 2 1 2 0
输出 #2复制
56
说明/提示
样例解释 1
你可以第 1 轮出 0,并在第 2,3 轮保持不变,如此输掉第 1,2 轮,但在第 3 轮中取胜,获得 2×10=20 分;
随后,你可以在第 4 轮中以扣 1 分为代价改出 1 ,并在第 4 轮中取得胜利,获得 2×100=200 分。
如此,你可以获得最高的总分 20+200−1=219。
数据范围
对于 30% 的测试点,保证 N≤15。
对于 60% 的测试点,保证 N≤100。
对于所有测试点,保证 N≤1,000;保证 0≤ai,bi≤106。
代码实现:
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
typedef long long ll;
const ll INF = 1e18;
int get_gain(int me, int opp, int ai)
{
if(me == opp) return ai;
if((me == 1 && opp == 0) || (me == 2 && opp == 1) || (me == 0 && opp == 2))
return 2 * ai;
return 0;
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(nullptr);
int N;
cin >> N;
vector<int> a(N + 1);
for(int i = 1; i <= N; i++) cin >> a[i];
vector<int> b(N);
for(int i = 1; i <= N - 1; i++) cin >> b[i];
vector<int> c(N + 1);
for(int i = 1; i <= N; i++) cin >> c[i];
vector<vector<vector<ll>>> dp(N + 1, vector<vector<ll>>(N, vector<ll>(3, -INF)));
for(int x = 0; x < 3; x++)
dp[1][0][x] = get_gain(x, c[1], a[1]);
for(int i = 2; i <= N; i++)
{
for(int t = 0; t <= i - 1; t++)
{
for(int x = 0; x < 3; x++)
{
if(dp[i-1][t][x] != -INF)
dp[i][t][x] = max(dp[i][t][x], dp[i-1][t][x] + get_gain(x, c[i], a[i]));
if(t >= 1)
{
for(int y = 0; y < 3; y++)
{
if(y == x) continue;
if(dp[i-1][t-1][y] != -INF)
{
ll val = dp[i-1][t-1][y] + get_gain(x, c[i], a[i]) - b[t];
dp[i][t][x] = max(dp[i][t][x], val);
}
}
}
}
}
}
ll ans = -INF;
for(int t = 0; t <= N - 1; t++)
for(int x = 0; x < 3; x++)
ans = max(ans, dp[N][t][x]);
cout << ans << endl;
return 0;
}
更多推荐


所有评论(0)