题解 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格是终点,游戏要求玩家控制一个乌龟 ...
随机推荐
- 灵感来袭,基于Redis的分布式延迟队列(续)
背景 上一篇(灵感来袭,基于Redis的分布式延迟队列)讲述了基于Java DelayQueue和Redis实现了分布式延迟队列,这种方案实现比较简单,应用于延迟小,消息量不大的场景是没问题的,毕竟J ...
- Arduino 中 EEprom 写入读取清除
转自:https://www.arduino.cn/thread-1157-1-1.html EEPROM (Electrically Erasable Programmable Read-Only ...
- 【题解】NOIP2018 赛道修建
题目戳我 \(\text{Solution:}\) 根据题目信息简化题意,是让你在树上找出\(m\)条路径使得路径长度最小值最大. 看到题第一感先二分一个答案,问题转化为如何选择一些路径使得它们最小值 ...
- 达梦产品技术支持培训-day8-DM8数据库备份与还原-实操
1.DM8的备份还原方法 Disql 工具:联机数据备份与还原,包括库备份.表空间备份与还原.表备份与还原: DMRMAN 工具:脱机数据库备份还原与恢复: 客户端工具 MANAGER和CONSOL ...
- 基于空镜像scratch创建一个新的Docker镜像
我们在使用Dockerfile构建docker镜像时,一种方式是使用官方预先配置好的容器镜像.优点是我们不用从头开始构建,节省了很多工作量,但付出的代价是需要下载很大的镜像包. 比如我机器上docke ...
- 每日一题 LeetCode 486. 预测赢家 【递推】【前缀和】【动态规划】
题目链接 https://leetcode-cn.com/problems/predict-the-winner/ 题目说明 题解 主要方法:递推:动态规划:前缀和 解释说明: 求前缀和 pre_nu ...
- MeteoInfo 新网站
MeteoInfo特别是MeteoInfoLab的推广需要写大量详细的帮助文档和示例程序,MeteoInfo原先的网站使用最原始的编写.html文件的方式来更新,效率实在太低,最近学习了一下Sphin ...
- day52 Pyhton 前端03
内容回顾 块级标签: div p h 列表:ol;ul;dl 表格:table 行内标签: span a i/em b/strong u/del 行内块: input textarea img 其他: ...
- Verilog基础入门——简单的语句块编写(一)
[题干] [代码] module top_module ( input in, output out ); assign out = ~in; endmodule 简单的实现一个非门
- C语言/C++编程学习:送给考计算机二级的同学:公共基础知识总结!
数据结构与算法 1.算法 算法:是指解题方案的准确而完整的描述. 算法不等于程序,也不等计算机方法,程序的编制不可能优于算法的设计. 算法的基本特征:是一组严谨地定义运算顺序的规则,每一个规则都是有效 ...