题目描述

乌龟棋的棋盘是一行\(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 【乌龟棋】的更多相关文章

  1. P1541 乌龟棋 题解(洛谷,动态规划递推)

    题目:P1541 乌龟棋 感谢大神的题解(他的写的特别好) 写一下我对他的代码的理解吧(哎,蒟蒻就这能这样...) 代码: #include<bits/stdc++.h> #define ...

  2. 洛谷P1541 乌龟棋 [2010NOIP提高组]

    P1541 乌龟棋 题目背景 小明过生日的时候,爸爸送给他一副乌龟棋当作礼物. 题目描述 乌龟棋的棋盘是一行N个格子,每个格子上一个分数(非负整数).棋盘第1格是唯一的起点,第N格是终点,游戏要求玩家 ...

  3. 【洛谷】P1541 乌龟棋(四维背包dp)

    题目背景 小明过生日的时候,爸爸送给他一副乌龟棋当作礼物. 题目描述 乌龟棋的棋盘是一行N个格子,每个格子上一个分数(非负整数).棋盘第1格是唯一的起点,第N格是终点,游戏要求玩家控制一个乌龟棋子从起 ...

  4. codevs1068 乌龟棋==洛谷P1541 乌龟棋

    P1541 乌龟棋 题目背景 小明过生日的时候,爸爸送给他一副乌龟棋当作礼物. 题目描述 乌龟棋的棋盘是一行N个格子,每个格子上一个分数(非负整数).棋盘第1格是唯一的起点,第N格是终点,游戏要求玩家 ...

  5. 洛谷 p1541乌龟棋

    洛谷 p1541乌龟棋 题目背景 小明过生日的时候,爸爸送给他一副乌龟棋当作礼物. 题目描述 乌龟棋的棋盘是一行NN个格子,每个格子上一个分数(非负整数).棋盘第1格是唯一的起点,第NN格是终点,游戏 ...

  6. 【题解】 Luogu P1541 乌龟棋总结 (动态规划)

    题目背景 小明过生日的时候,爸爸送给他一副乌龟棋当作礼物. 题目描述 乌龟棋的棋盘是一行N个格子,每个格子上一个分数(非负整数).棋盘第1格是唯一的起点,第N格是终点,游戏要求玩家控制一个乌龟棋子从起 ...

  7. Luogu P1541 乌龟棋(NOIP2010TG)

    自己的第一篇博文 祭一下祭一下 题目背景 小明过生日的时候,爸爸送给他一副乌龟棋当作礼物. 题目描述 乌龟棋的棋盘是一行N个格子,每个格子上一个分数(非负整数).棋盘第1格是唯一的起点,第N格是终点, ...

  8. [洛谷P1541] 乌龟棋

    洛谷题目链接:乌龟棋 题目背景 小明过生日的时候,爸爸送给他一副乌龟棋当作礼物. 题目描述 乌龟棋的棋盘是一行N个格子,每个格子上一个分数(非负整数).棋盘第1格是唯一的起点,第N格是终点,游戏要求玩 ...

  9. dp——洛谷 P1541 乌龟棋 —— by hyl天梦

    题目:(转自 https://www.luogu.com.cn/problem/P1541) 题目描述 乌龟棋的棋盘是一行NN个格子,每个格子上一个分数(非负整数).棋盘第1格是唯一的起点,第NN格是 ...

  10. P1541 乌龟棋(DP)

    题目背景 小明过生日的时候,爸爸送给他一副乌龟棋当作礼物. 题目描述 乌龟棋的棋盘是一行NNN个格子,每个格子上一个分数(非负整数).棋盘第1格是唯一的起点,第NNN格是终点,游戏要求玩家控制一个乌龟 ...

随机推荐

  1. 灵感来袭,基于Redis的分布式延迟队列(续)

    背景 上一篇(灵感来袭,基于Redis的分布式延迟队列)讲述了基于Java DelayQueue和Redis实现了分布式延迟队列,这种方案实现比较简单,应用于延迟小,消息量不大的场景是没问题的,毕竟J ...

  2. 小伙伴问我:如何搭建Maven私服?我连夜肝了这篇实战文章!!

    写在前面 十一假期期间,也有很多小伙伴不忘学习呀,看来有很多小伙伴想通过十一长假来提升自己的专业技能!这不,就有小伙伴在微信上问我:如何搭建Maven私服?让我专门推一篇搭建Maven私服的文章.安排 ...

  3. 076 01 Android 零基础入门 02 Java面向对象 01 Java面向对象基础 01 初识面向对象 01 Java面向对象导学

    076 01 Android 零基础入门 02 Java面向对象 01 Java面向对象基础 01 初识面向对象 01 Java面向对象导学 本文知识点:Java面向对象导学 说明:因为时间紧张,本人 ...

  4. C1853 编译器错误:fatal error C1853: 'pjtname.pch' precompiled header file is from a previous

    转载:https://www.cnblogs.com/emanlee/archive/2010/10/16/1852998.html 用VC++ 2008 编写C语言程序,编译出现错误: 预编译头文件 ...

  5. 头文件afx.h作用

    转载:https://blog.csdn.net/OnceMonkeyG/article/details/95723290 一些定义与设置,为MFC提供最基本支持,将各种松散的东西组织起来,同时为MF ...

  6. 【题解】CF1324F

    Question 题目大意:每个点不是黑点就是白点,求以每一个点为根时,选择出一个联通块,使得白点数与黑点数之差最大(白减黑). \(Solution\) 考虑先跑一遍\(dp\). 可以写出一个比较 ...

  7. 引用类型之Array(二)

    操作方法 concat( ) concat() 方法用于连接两个或多个数组. 该方法不会改变现有的数组,而仅仅会返回被连接数组的一个副本. 语法 arrayObject.concat(arrayX,a ...

  8. OracleOggan安装并测试同步数据步骤!

    Oracle Golden Gate (ogg)安装使用说明 Golden Gate(简称OGG)提供异构环境下交易数据的实时捕捉.变换.投递等功能. OGG支持的异构环境有: OGG的特性: ①对生 ...

  9. docker overlay原理

    周末两天研究了一下docker overlay网络的原理,因为我本身对go语言不太熟悉,直接看docker官方的libnetwork库看不太懂,看linux内核的vxlan代码又粗心大意,导致有一个环 ...

  10. IDEA 简拼输入

    1. sout = System.out.println(); 2. soutp = System.out.println(""); 3. soutv = System.out.p ...