CJOJ 1087 【NOIP2010】乌龟棋 / Luogu 1541 乌龟棋(动态规划)
CJOJ 1087 【NOIP2010】乌龟棋 / Luogu 1541 乌龟棋(动态规划)
Description
小明过生日的时候,爸爸送给他一副乌龟棋当作礼物。
乌龟棋的棋盘是一行N个格子,每个格子上一个分数(非负整数)。棋盘第1格是唯一的起点,第N格是终点,游戏要求玩家控制一个乌龟棋子从起点出发走到终点。
乌龟棋中M张爬行卡片,分成4种不同的类型(M张卡片中不一定包含所有4种类型的卡片,见样例),每种类型的卡片上分别标有1、2、3、4四个数字之一,表示使用这种卡片后,乌龟棋子将向前爬行相应的格子数。游戏中,玩家每次需要从所有的爬行卡片中选择一张之前没有使用过的爬行卡片,控制乌龟棋子前进相应的格子数,每张卡片只能使用一次。
游戏中,乌龟棋子自动获得起点格子的分数,并且在后续的爬行中每到达一个格子,就得到该格子相应的分数。玩家最终游戏得分就是乌龟棋子从起点到终点过程中到过的所有格子的分数总和。
很明显,用不同的爬行卡片使用顺序会使得最终游戏的得分不同,小明想要找到一种卡片使用顺序使得最终游戏得分最多。
现在,告诉你棋盘上每个格子的分数和所有的爬行卡片,你能告诉小明,他最多能得到多少分吗?
Input
每行中两个数之间用一个空格隔开。
第1行2个正整数N和M,分别表示棋盘格子数和爬行卡片数。
第2行_N个非负整数,a1, a2,……, aN,其中ai表示棋盘第i个格子上的分数。
第3行M个整数,b1,b2,……, bM,表示M张爬行卡片上的数字。
输入数据保证到达终点时刚好用光M张爬行卡片,即N−1=ΣM (ΣM表示M张卡片数字的和)
Output
输出只有1行,1个整数,表示小明最多能得到的分数。
Sample Input
9 5
6 10 14 2 8 8 18 5 17
1 3 1 2 1
Sample Output
73
Http
CJOJ:http://oj.changjun.com.cn/problem/detail/pid/1087
Luogu:https://www.luogu.org/problem/show?pid=1541
Source
动态规划
解决思路
我们首先想到的是令F[x][a][b][c][d]表示走到x格时用了a格爬1格,b个爬2格,c个爬3格,d个爬4个的卡片所能有的最大得分。那么我们就能得到一个初始的动态转移方程
\[F[x][a][b][c][d]=max \begin{cases} F[x-1][a-1][b][c][d]& \text{a!=0}\\F[x-2][a][b-1][c][d]& \text{b!=0} \\ F[x-3][a][b][c-1][d]& \text{c!=0} \\ F[x-4][a][b][c][d-1]& \text{d!=0}\end{cases} +Value[x]\]
但是这样是通不过空间限制的。题中已经给出了用这M张卡片一定能到达n格,所以我们可以省掉x那一维数组,直接用a,b,c,d推出x,所以动态转移方程为
\[F[a][b][c][d]=max \begin{cases} F[a-1][b][c][d]& \text{a!=0}\\F[a][b-1][c][d]& \text{b!=0} \\ F[a][b][c-1][d]& \text{c!=0} \\ F[a][b][c][d-1]& \text{d!=0}\end{cases} +Value[a+b*2+c*3+d*4+1]\]
注意最后要+1,因为起始格是第一格。
为了简便,我们还是使用记忆化的方法。
代码
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
using namespace std;const int maxN=351;
const int maxC=41;
const int inf=2147483647;int n,m;
int Card[10]={0};
int Value[maxN];
int F[maxC][maxC][maxC][maxC];int dfs(int a,int b,int c,int d);int main()
{int x;cin>>n>>m;for (int i=1;i<=n;i++)cin>>Value[i];for (int i=1;i<=m;i++){cin>>x;Card[x]++;//直接累加到同类卡片的计数器中}memset(F,-1,sizeof(F));F[0][0][0][0]=Value[1];F[Card[1]][Card[2]][Card[3]][Card[4]]=dfs(Card[1],Card[2],Card[3],Card[4]);cout<<F[Card[1]][Card[2]][Card[3]][Card[4]]<<endl;return 0;
}int dfs(int a,int b,int c,int d)//记忆化搜索
{if (F[a][b][c][d]!=-1)return F[a][b][c][d];int k=a+b*2+c*3+d*4+1;if (a!=0)F[a][b][c][d]=max(F[a][b][c][d],dfs(a-1,b,c,d));if (b!=0)F[a][b][c][d]=max(F[a][b][c][d],dfs(a,b-1,c,d));if (c!=0)F[a][b][c][d]=max(F[a][b][c][d],dfs(a,b,c-1,d));if (d!=0)F[a][b][c][d]=max(F[a][b][c][d],dfs(a,b,c,d-1));F[a][b][c][d]+=Value[k];return F[a][b][c][d];
}
转载于:https://www.cnblogs.com/SYCstudio/p/7138161.html
CJOJ 1087 【NOIP2010】乌龟棋 / Luogu 1541 乌龟棋(动态规划)相关推荐
- Luogu 1541 乌龟棋
题目链接:https://www.luogu.org/problemnew/show/P1541 思路: 考虑若一张卡片被使用过,则可以从它当时的状态来进行转移. 故设$f[i][j][k][l]$表 ...
- 黑白棋,又叫翻转棋(Reversi)、苹果棋或奥赛罗棋(Othello)。棋盘共有8行8列共64格。开局时,棋盘正中央的4格先置放黑白相隔的4枚棋子。双方轮流落子,只要落子和棋盘上任一枚己方的棋子
黑白棋,又叫翻转棋(Reversi).苹果棋或奥赛罗棋(Othello).棋盘共有8行8列共64格. 开局时,棋盘正中央的4格先置放黑白相隔的4枚棋子.双方轮流落子,只要落子和棋盘上任一枚己方的棋子在 ...
- c语言入门——三子棋(N子棋)
目录 前言 一.什么是三子棋? 二.三子棋(N子棋)设计思路 1.主函数 2.数组的初始化 3.菜单 4.游戏主体 (1).棋盘 (2).下棋 (3).判断胜负 三.最终代码 源文件1 源文件2 头文 ...
- python翻转棋_奥赛罗棋reverse
作者,持牌照消费金融模型经理,发明国家算法专利,国内大型医药数据中心担任过数据库负责人.和中科院,清华大学,百度,腾讯,爱奇艺等平台保持长期项目合作.擅长python 机器学习,应用于游戏,医疗,金融 ...
- 三子棋(井字棋)的实现
三子棋(井字棋)的玩法规则 两个玩家,一个打圈(O),一个打叉(X),(用什么符号可以根据自己想法使用)轮流在3乘3的格上打自己的符号,最先以横.直.斜连成一线则为胜.如果双方都下得正确无误,将得和局 ...
- html5独立钻石棋,自制独立钻石棋
在女儿的杂志上看到了独立钻石棋,以前从来没听说过,至少对我来说是非常新鲜的.女儿是对所有的新鲜事物都有浓厚的兴趣,自己就极其想尝试,我说,照着做吧. 女儿说干就干,找了一个白纸,在上面画了棋盘,但是没 ...
- 推子五子棋、连六棋(六子棋)
目录 推子五子棋 连六棋 推子五子棋 在线play 规则: 在5*5的盘面上下五子棋,正常肯定会下满25个格子,然后开始推子操作: 在一个格子落子,这个格子以及这一列它下面的(1-5个)所有格子都往下 ...
- c语言实现三子棋(井子棋)
目录 前言 一.初步构思 二.实现步骤 1.text.c 2.game.c 3.game.h 总结 前言 通过对c语言的初步学习,我们可以用循环,数组,函数的相关知识写一个简单的游戏.增强自信心的同时 ...
- C语言自制小游戏:三子棋(井字棋)智能下棋补充
目录 一.前期准备 二.逻辑与程序实现 1.连珠 ①横向连珠 ②纵向连珠 ③斜向连珠 ④函数完善 2.堵棋 ①横向堵棋 ②纵向堵棋 ③斜向堵棋 3.整理函数 ①整理AI_Computer函数 ②修改C ...
最新文章
- Flutter GitHub Travis CI 搭建
- Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.3:compile (default-compile)
- Programming WCF Services 学习笔记四、Instance Management
- 快速排序(quick sort) C++
- Java_JDBC_MySql
- java远程下载文件到本地_java远程下载文件到本地
- 可怕!那些你看不到的进程
- 机器学习--组合分类方法之AdaBoost算法实战(单层决策树原理代码详解)
- ios 企业签名需要源文件么_苹果ios企业签名是什么?苹果ios企业签名了解一下!...
- Android反编译软件android killer教程
- 商务办公软件应用与实践【9】
- ora01017 linux,Oracle linux 7.5安装oracle 12c dg一直提示ORA-01017
- http请求 405错误
- 如果忘记了学信网手机号可以试着这样找回
- 9宫格实现微信朋友圈图片点击放大缩小弹簧效果
- 014 Unbox failed! RequestError: Error: getaddrinfo ENOENT raw.githubusercontent.com raw.githubuserco
- 刚刚手贱把D盘设置为活动分区,导致无法进系统。来看看我的解决方法
- 广告营销DSP和DMP概念解释
- Python 计算任意两向量之间的夹角
- 在一张图片上显示热力图(前端)
热门文章
- Python实现访问者模式
- JS高级——手写call()、apply()、bind()
- 五、手动取消ajax请求 解决重复发送请求问题
- LeetCode 2119. 反转两次的数字
- LeetCode 1564. 把箱子放进仓库里 I(排序)
- 天池 在线编程 Character deletion
- LeetCode 568. 最大休假天数(DP)
- LeetCode 581. 最短无序连续子数组(排序单调栈)
- LeetCode 102. 二叉树的层次遍历(BFS)
- 怎么读取matlab程序包,Nifti程序包,用于写入,读取和处理医学影像,适用于MATLAB