题解 P1541 【乌龟棋】
题目描述
乌龟棋的棋盘是一行\(N\)个格子,每个格子上一个分数(非负整数)。棋盘第\(1\)格是唯一的起点,第\(N\)格是终点,游戏要求玩家控制一个乌龟棋子从起点出发走到终点。
乌龟棋中\(M\)张爬行卡片,分成\(4\)种不同的类型 ,每种类型的卡片上分别标有 \(1,2,3,4\) 四个数字之一,表示使用这种卡片后,乌龟棋子将向前爬行相应的格子数。游戏中,玩家每次需要从所有的爬行卡片中选择一张之前没有使用过的爬行卡片,控制乌龟棋子前进相应的格子数,每张卡片只能使用一次。
游戏中,乌龟棋子自动获得起点格子的分数,并且在后续的爬行中每到达一个格子,就得到该格子相应的分数。玩家最终游戏得分就是乌龟棋子从起点到终点过程中到过的所有格子的分数总和。
很明显,用不同的爬行卡片使用顺序会使得最终游戏的得分不同,小明想要找到一种卡片使用顺序使得最终游戏得分最多。
现在,告诉你棋盘上每个格子的分数和所有的爬行卡片,你能告诉小明,他最多能得到多少分吗?
题目链接
思路
我们发现,每种卡片的数量很少,并且我们的移动格数只和我们使用的牌有关,所以我们可以考虑将每一种牌的使用数量作为状态来进行\(DP\) 。我们假设 \(dp[p_1][p_2][p_3][p_4]\)表示标有\(1\)的卡使用了\(p_1\)张,……,标有\(4\) 的卡使用了\(p_4\) 张所能获得的最大分。
接下来考虑状态如何转移。
记当前位置 \(place=1+p_1+2p_2+3p_3+p_4\)。我们考虑当前状态下上一次用了哪一种卡片。
如果 \(p_1\le 0\) ,那么最后一次可以使用了一张标有 \(1\) 的卡片,此时\(dp[p_1][p_2][p_3][p_4]=dp[p_1][p_2][p_3][p_4]+a[place]\) 。
如果 \(p_2\le 0\) ,那么 \(dp[p_1][p_2][p_3][p_4] = dp[p_1][p_2 - 1][p_3][p_4] + a[place]\) 。
如果 \(p_3\le 0\) ,那么 \(dp[p_1][p_2][p_3][p_4] = dp[p_1][p_2][p_3 - 1][p_4] + a[place]\) 。
如果 \(p_4\le 0\) ,那么 \(dp[p_1][p_2][p_3][p_4] = dp[p_1][p_2][p_3][p_4 - 1] + a[place]\) 。
程序实现中四者取最大值即可。
初始条件为:\(dp[0][0][0][0] = a[1]\) ,即不使用任何卡片时,在第一格,自动获得了第一格的分数。
假设给出的标有 \(1,2,3,4\) 的卡片数量分别为 \(n_1,n_2,n_3,n_4\),那么最终答案就是 \(dp[n_1][n_2][n_3][n_4]\) 。
而 \(n_1,n_2,n_3,n_4\) 可以放在一个数组中,因此最终总体复杂度约为 \(\Theta((\frac{m}{4})^4)\) 。
代码
#include <bits/stdc++.h>
using namespace std;
const int N=360;
const int M=45;
int k,m;
int a[N],dp[M][M][M][M];
int n[5];
int main() {
cin>>k>>m;
for(int i=1;i<=k;i++) cin>>a[i];
for(int i=1;i<=m;i++) {
int x;
cin>>x;
n[x]++;
}
dp[0][0][0][0]=a[1]; //初始化
for(int p1=0;p1<=n[1];p1++) {
for(int p2=0;p2<=n[2];p2++) {
for(int p3=0;p3<=n[3];p3++) {
for(int p4=0;p4<=n[4];p4++) {
int place=1+p1+2*p2+3*p3+4*p4;
if(p1>0) dp[p1][p2][p3][p4]=max(dp[p1][p2][p3][p4],dp[p1-1][p2][p3][p4]+a[place]);
if(p2>0) dp[p1][p2][p3][p4]=max(dp[p1][p2][p3][p4],dp[p1][p2-1][p3][p4]+a[place]);
if(p3>0) dp[p1][p2][p3][p4]=max(dp[p1][p2][p3][p4],dp[p1][p2][p3-1][p4]+a[place]);
if(p4>0) dp[p1][p2][p3][p4]=max(dp[p1][p2][p3][p4],dp[p1][p2][p3][p4-1]+a[place]);
}
}
}
}
cout<<dp[n[1]][n[2]][n[3]][n[4]]<<endl;
return 0;
}
题解 P1541 【乌龟棋】的更多相关文章
- P1541 乌龟棋 题解(洛谷,动态规划递推)
题目:P1541 乌龟棋 感谢大神的题解(他的写的特别好) 写一下我对他的代码的理解吧(哎,蒟蒻就这能这样...) 代码: #include<bits/stdc++.h> #define ...
- 洛谷P1541 乌龟棋 [2010NOIP提高组]
P1541 乌龟棋 题目背景 小明过生日的时候,爸爸送给他一副乌龟棋当作礼物. 题目描述 乌龟棋的棋盘是一行N个格子,每个格子上一个分数(非负整数).棋盘第1格是唯一的起点,第N格是终点,游戏要求玩家 ...
- 【洛谷】P1541 乌龟棋(四维背包dp)
题目背景 小明过生日的时候,爸爸送给他一副乌龟棋当作礼物. 题目描述 乌龟棋的棋盘是一行N个格子,每个格子上一个分数(非负整数).棋盘第1格是唯一的起点,第N格是终点,游戏要求玩家控制一个乌龟棋子从起 ...
- codevs1068 乌龟棋==洛谷P1541 乌龟棋
P1541 乌龟棋 题目背景 小明过生日的时候,爸爸送给他一副乌龟棋当作礼物. 题目描述 乌龟棋的棋盘是一行N个格子,每个格子上一个分数(非负整数).棋盘第1格是唯一的起点,第N格是终点,游戏要求玩家 ...
- 洛谷 p1541乌龟棋
洛谷 p1541乌龟棋 题目背景 小明过生日的时候,爸爸送给他一副乌龟棋当作礼物. 题目描述 乌龟棋的棋盘是一行NN个格子,每个格子上一个分数(非负整数).棋盘第1格是唯一的起点,第NN格是终点,游戏 ...
- 【题解】 Luogu P1541 乌龟棋总结 (动态规划)
题目背景 小明过生日的时候,爸爸送给他一副乌龟棋当作礼物. 题目描述 乌龟棋的棋盘是一行N个格子,每个格子上一个分数(非负整数).棋盘第1格是唯一的起点,第N格是终点,游戏要求玩家控制一个乌龟棋子从起 ...
- Luogu P1541 乌龟棋(NOIP2010TG)
自己的第一篇博文 祭一下祭一下 题目背景 小明过生日的时候,爸爸送给他一副乌龟棋当作礼物. 题目描述 乌龟棋的棋盘是一行N个格子,每个格子上一个分数(非负整数).棋盘第1格是唯一的起点,第N格是终点, ...
- [洛谷P1541] 乌龟棋
洛谷题目链接:乌龟棋 题目背景 小明过生日的时候,爸爸送给他一副乌龟棋当作礼物. 题目描述 乌龟棋的棋盘是一行N个格子,每个格子上一个分数(非负整数).棋盘第1格是唯一的起点,第N格是终点,游戏要求玩 ...
- dp——洛谷 P1541 乌龟棋 —— by hyl天梦
题目:(转自 https://www.luogu.com.cn/problem/P1541) 题目描述 乌龟棋的棋盘是一行NN个格子,每个格子上一个分数(非负整数).棋盘第1格是唯一的起点,第NN格是 ...
- P1541 乌龟棋(DP)
题目背景 小明过生日的时候,爸爸送给他一副乌龟棋当作礼物. 题目描述 乌龟棋的棋盘是一行NNN个格子,每个格子上一个分数(非负整数).棋盘第1格是唯一的起点,第NNN格是终点,游戏要求玩家控制一个乌龟 ...
随机推荐
- 【Java】socket编程,输入输出中的问题
BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream())); PrintWri ...
- C++有子对象的派生类的构造函数
转载:https://blog.csdn.net/qq1169091731/article/details/50934588?utm_source=blogxgwz6 类的数据成员不但可以是标准型(如 ...
- interp1一维数据插值在matlab中的用法
转载:https://ww2.mathworks.cn/help/matlab/ref/interp1.html?s_tid=srchtitle#btwp6lt-2_1 interp1 一维数据插值( ...
- 【Go语言入门系列】Go语言工作目录介绍及命令工具的使用
[Go语言入门系列]前面的文章: [保姆级教程]手把手教你进行Go语言环境安装及相关VSCode配置 [Go语言入门系列](八)Go语言是不是面向对象语言? [Go语言入门系列](九)写这些就是为了搞 ...
- HanLP的分词统计
HanLP的分词效果鄙人研究了HanLP,他的分词效果确实还可以,而且速度也比较快,10的数据是9000毫秒 @SneakyThrows@Overridepublic LinkedHashMap< ...
- 55.Qt-将界面程序封装成静态库
1.生成dll 然后选择创建静态链接库: 创建的时候,记得勾选QtGui,并且修改pro文件,添加下面1句(这样就可以创建界面了): 修改staticlib.cpp: #include "s ...
- MeteoInfoLab脚本示例:MERRA HDF数据
MERRA是NOAA的一种再分析资料,HDF数据遵循COARDS协议,读取比较简单.脚本程序: #Add data file folder = 'D:/Temp/hdf/' fns = 'MERRA3 ...
- webpack5文档解析(上)
webpack5 声明:所有的文章demo都在我的仓库里 webpack5 起步 概念 webpack是用于编译JavaScript模块. 一个文件依赖另一个文件,包括静态资源(图片/css等),都会 ...
- day33 Pyhton 常用模块03
一.正则表达式: 1.元字符 . 匹配除换行符以外的任意字符 \w 匹配字母或数字或下划线 \s 匹配任意的空白符 \d 匹配数字 \n 匹配一个换行符 \t 匹配一个制表符 \b 匹配一个单词的结尾 ...
- Verilog基础入门——简单的语句块编写(一)
[题干] [代码] module top_module ( input in, output out ); assign out = ~in; endmodule 简单的实现一个非门