题面

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

样例输入1:

9 5

6 10 14 2 8 8 18 5 17

1 3 1 2 1

样例输入2:

13 8

4 96 10 64 55 13 94 53 5 24 89 8 30

1 1 1 1 1 2 4 1

Sample Output

样例输出1:

73

样例输出2:

455

Hint

【输入输出样例1说明】

小明使用爬行卡片顺序为1,1,3,1,2,得到的分数为6+10+14+8+18+17=73。注意, 由于起点是1,所以自动获得第1格的分数6。

【数据范围】

对于30%的数据有1≤N≤30,1≤M≤12。

对于50%的数据有1≤N≤120,1≤M≤50,且4种爬行卡片,每种卡片的张数不会超过20。

对于100%的数据有1≤N≤350,1≤M≤120,且4种爬行卡片,每种卡片的张数不会超过40;0≤ai≤100,1≤i≤N;1≤bi≤4,1≤i≤M。输入数据保证N−1=ΣMibi。

题解

一道比较简单的DP问题

一开始我还在思考五维DP

事实上,关于走出去的步数可以由卡片的使用情况直接推出

因此,只需要四维DP即可

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
inline int read()
{
register int x=0,t=1;
register char ch=getchar();
while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
if(ch=='-'){t=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-48;ch=getchar();}
return x*t;
}
//f[x][y][z][w]表示
//1步的卡片用x张,2步的卡片用y张
//3步的卡片用z张,4步的卡片用w张
//的时候,能够拿到最大的分数
int f[41][41][41][41];
int n,m;
int A[500],B[5];
int main()
{
n=read();
m=read();
for(int i=1;i<=n;++i)
A[i]=read();
for(int i=1;i<=m;++i)
B[read()]++;
f[0][0][0][0]=A[1];//赋初值
for(int i=0;i<=B[1];++i)
for(int j=0;j<=B[2];++j)
for(int k=0;k<=B[3];++k)
for(int l=0;l<=B[4];++l)
{
int d=A[i+j+j+k+k+k+l+l+l+l+1];
if(i!=0)
f[i][j][k][l]=max(f[i][j][k][l],f[i-1][j][k][l]+d);
if(j!=0)
f[i][j][k][l]=max(f[i][j][k][l],f[i][j-1][k][l]+d);
if(k!=0)
f[i][j][k][l]=max(f[i][j][k][l],f[i][j][k-1][l]+d);
if(l!=0)
f[i][j][k][l]=max(f[i][j][k][l],f[i][j][k][l-1]+d);
}
cout<<f[B[1]][B[2]][B[3]][B[4]]<<endl;
return 0;
}

【洛谷1541】【CJOJ1087】【NOIP2010】乌龟棋的更多相关文章

  1. 洛谷P4363 一双木棋 chess

    洛谷P4363 一双木棋 chess 省选最水的一道题了. 且看我数个月AC一道题...... 具体是这样的:我们发现这个下了棋的地方一定形成一个锯齿形,那么怎么状态压缩呢? 维护轮廓线! 从左下角出 ...

  2. NOIP2010乌龟棋[DP 多维状态]

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

  3. NOIP2010 乌龟棋

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

  4. 洛谷 1541 NOIp2010提高组 乌龟棋

    [题解] 很容易想到这是一个DP,f[i][j][k][l]表示4种卡片分别用了多少张,那么转移方程就是f[i][j][k][l]=Max(f[i-1][j][k][l],f[i][j-1][k][l ...

  5. 洛谷 1541 乌龟棋——dp

    题目:https://www.luogu.org/problemnew/show/P1541 以用了几张牌为阶段.注意知道了用了4种牌各几张后,当前位置就是确定的,所以不用记录什么的. #includ ...

  6. 洛谷$1541$ 乌龟棋 线性$DP$

    Luogu   CH Sol f[i]表示走到第i个格子时获得的最大分数 发现转移与各个爬行卡片的数量有关,一共只有4种卡片 所以就把这四种卡片的已使用张数也放进状态,f[i][a][b][c][d] ...

  7. 洛谷1541 乌鬼棋 dp入门

    题目链接:https://www.luogu.com.cn/problem/P1541 给定一个序列和一个操作序列,操作序列中只有1234四个数字,表示可以前进的步数,初始在1处,操作最后一定会全部用 ...

  8. 题解 洛谷P5380 【[THUPC2019]鸭棋】

    就是一道大模拟. 首先,来解释一下复杂的题意: 给你一些棋子,每个棋都有不同的走法,开局是回归原位. 接下来,题目会给你一个虚拟的走子操作(注意不一定真实),你所需要判断当前操作是否正确.若不正确,输 ...

  9. 洛谷P4363 一双木棋chess [九省联考2018] 搜索+hash

    正解:记搜+hash 解题报告: 传送门! 因为看到nm范围特别小,,,所以直接考虑爆搜(bushi 先考虑爆搜之后再想优化什么的嘛QwQ 首先对这种都要最优的,就可以直接把答案设为针对某一方,然后题 ...

随机推荐

  1. 【Oracle】-初识PL/SQL

    在最近的工作中要用到存储过程和函数,索性把PL/SQL整体的看一下.之前看过基本书和园子里的博文,在这里将所学简单总结. 一.基本语句 1.大小写 2.分隔符  --  : 3.引用字符串  --   ...

  2. mac攻略(1) -- 简单配置php开发环境

    [http://www.cnblogs.com/redirect/p/6112154.html]   最简单直接的方式还是使用 Mac 上自带的 Apache 和 PHP.   1.启动 Apache ...

  3. PHP 批量获取指定目录下的文件列表(递归,穿透所有子目录)

    //调用 $dir = '/Users/xxx/www'; $exceptFolders = array('view','test'); $exceptFiles = array('BaseContr ...

  4. Apache设置二级域名和虚拟主机

    apache  httpd.conf 最后: ------------------------------NameVirtualHost *:80<VirtualHost *:80>    ...

  5. levmar ndk 编译

         levmar是一个强大的和高效率的C/C++库,采用Levenberg - 马奎德(LM)优化算法, 主要是为了解决非线性最小二乘问题.官网是:http://users.ics.forth. ...

  6. Java经典编程题50道之十

    一球从100米高度自由落下,每次落地后反跳回原高度的一半:再落下……求它在第10次落地时,共经过多少米?第10次反弹多高? public class Example10 {    public sta ...

  7. bzoj 1171 大sz的游戏& 2892 强袭作战 (线段树+单调队列+永久性flag)

    大sz的游戏 Time Limit: 50 Sec  Memory Limit: 357 MBSubmit: 536  Solved: 143[Submit][Status][Discuss] Des ...

  8. spring 运行时属性值注入

    继续spring学习,今天介绍两种外部属性值注入的方式.当你需要读取配置信息时,可以快速读取. 开始之前先创建属性文件site.properties,放在classpath下面 #数据库配置 ### ...

  9. alter 和 update的区别?

    alter用来增加或者减少列,alter stuednt add name vachar2(30): update用来更改表中的数据:update student set sutudent.name ...

  10. PHP如何防止XSS攻击

    PHP防止XSS跨站脚本攻击的方法:是针对非法的HTML代码包括单双引号等,使用htmlspecialchars()函数 . 在使用htmlspecialchars()函数的时候注意第二个参数, 直接 ...