当前位置: 首页 > article >正文

GSEP 7级T2真题 [202312]纸牌游戏

题目描述

[GESP202312 七级] 纸牌游戏

题目描述

你和小杨在玩一个纸牌游戏。

你和小杨各有 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

样例输入 #1

4
1 2 10 100
1 100 1
1 1 2 0

样例输出 #1

219

样例 #2

样例输入 #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。

样例输入 复制
4
1 2 10 100
1 100 1
1 1 2 0
样例输出 复制
219

思路分析: 

懒得在文章里写了,部分都在文章注释里了。

AC代码:

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
ll n;
ll sco[1005]; // 得分数组
ll loss[1005]; // 失分数组(前缀和)
ll arr[1005]; // 对手 n 轮出牌
ll dp[1005][3][1005]; // dp[i][j][k]: 第 i 场,出 j,换牌 k 次的最大分数
int main() {
	cin >> n;
	for (int i = 1; i <= n; i ++) cin >> sco[i]; // 得分数组
	for (int i = 1; i < n; i ++) { // 换牌至多只有 n-1 次
		cin >> loss[i];
		loss[i] += loss[i - 1]; // 预处理前缀和
	}
	for (int i = 1; i <= n; i ++) cin >> arr[i]; // 输入对手的出牌方案

	for (int i = 1; i <= n; i ++) { // 状态转移
		for (int k = 0; k < i; k ++) { // 注意 k 只需要枚举到 i-1
			if (arr[i] == 0) {
				dp[i][0][k] = max(dp[i - 1][0][k],
				                  max(dp[i - 1][1][k - 1],
				                      dp[i - 1][2][k - 1])) + sco[i];

				dp[i][1][k] = max(dp[i - 1][0][k - 1],
				                  max(dp[i - 1][1][k],
				                      dp[i - 1][2][k - 1])) + 2 * sco[i];

				dp[i][2][k] = max(dp[i - 1][0][k - 1],
				                  max(dp[i - 1][1][k - 1],
				                      dp[i - 1][2][k]));
			} else if (arr[i] == 1) {
				dp[i][0][k] = max(dp[i - 1][0][k],
				                  max(dp[i - 1][1][k - 1],
				                      dp[i - 1][2][k - 1]));

				dp[i][1][k] = max(dp[i - 1][0][k - 1],
				                  max(dp[i - 1][1][k],
				                      dp[i - 1][2][k - 1])) + sco[i];

				dp[i][2][k] = max(dp[i - 1][0][k - 1],
				                  max(dp[i - 1][1][k - 1],
				                      dp[i - 1][2][k])) + 2 * sco[i];
			} else if (arr[i] == 2) {
				dp[i][0][k] = max(dp[i - 1][0][k],
				                  max(dp[i - 1][1][k - 1],
				                      dp[i - 1][2][k - 1])) + 2 * sco[i];

				dp[i][1][k] = max(dp[i - 1][0][k - 1],
				                  max(dp[i - 1][1][k],
				                      dp[i - 1][2][k - 1]));

				dp[i][2][k] = max(dp[i - 1][0][k - 1],
				                  max(dp[i - 1][1][k - 1],
				                      dp[i - 1][2][k])) + sco[i];
			}
		}
	}
	// 统计答案
	ll ans = 0;
	for (int k = 0; k < n; k ++) {
		for (int j = 0; j < 3; j ++) {
			ans = max(ans, dp[n][j][k] - loss[k]);
		}
	}
	cout << ans << endl;
	return 0;
}

 


http://www.kler.cn/a/304440.html

相关文章:

  • 设备接入到NVR管理平台EasyNVR多品牌NVR管理工具/设备的音视频配置参考
  • sql server启用远程连接与修改默认端口
  • 11.11比赛总结
  • A20红色革命文物征集管理系统
  • 机器学习中的分类:决策树、随机森林及其应用
  • 《大模型应用开发极简入门》笔记
  • [pytorch] 训练节省显存的技巧
  • Kizuna AI——AI驱动虚拟偶像,AI分析观众的反应和互动,应用娱乐、直播和广告行业
  • Linux(RedHat或CentOS)下如何开启telnet服务
  • 【时时三省】(C语言基础)指针进阶 例题7
  • SQLITE3数据库实现信息的增删改查
  • ensp—路由过滤、路由引入、路由策略
  • 【基础知识复习 - 随机练习题】
  • 1935. 公交换乘(transfer)
  • 常用环境部署(二十)——docker部署OpenProject
  • 基于华为云服务器的网页部署
  • 【Android】使用和风天气API获取天气数据吧!(天气预报系列之一)
  • ARCGIS PRO DSK MapTool
  • 使用Azure Devops Pipeline将Docker应用部署到你的Raspberry Pi上
  • 【Hadoop|MapReduce篇】Hadoop序列化概述
  • LabVIEW FIFO详解
  • 分享六款小众宝藏软件,建议收藏!
  • golang os.Eixt的介绍和使用
  • 【C++】vector常见用法
  • 数字化大屏解决方案 - GoView
  • 如何通俗易懂的解释TON的智能合约