乌龟棋
问题 B: 乌龟棋
时间限制: 1 Sec 内存限制: 128 MB提交: 83 解决: 51
[提交] [状态] [讨论版] [命题人:admin]
题目描述
小明过生日的时候,爸爸送给他一副乌龟棋当作礼物。
乌龟棋的棋盘是一行 N 个格子,每个格子上一个分数(非负整数)。棋盘第 1 格是唯一的起点,第 N 格是终点,游戏要求玩家控制一个乌龟棋子从起点出发走到终点。
乌龟棋中 M 张爬行卡片,分成 4 种不同的类型(M 张卡片中不一定包含所有 4 种类型的卡片,见样例),每种类型的卡片上分别标有 1、2、3、4 四个数字之一,表示使用这种卡片后,乌龟棋子将向前爬行相应的格子数。游戏中,玩家每次需要从所有的爬行卡片中选择一张之前没有使用过的爬行卡片,控制乌龟棋子前进相应的格子数,每张卡片只能使用一次。游戏中,乌龟棋子自动获得起点格子的分数,并且在后续的爬行中每到达一个格子,就得到该格子相应的分数。玩家最终游戏得分就是乌龟棋子从起点到终点过程中到过的所有格子的分数总和。
很明显,用不同的爬行卡片使用顺序会使得最终游戏的得分不同,小明想要找到一种卡片使用顺序使得最终游戏得分最多。
现在,告诉你棋盘上每个格子的分数和所有的爬行卡片,你能告诉小明,他最多能得到多少分吗?
乌龟棋的棋盘是一行 N 个格子,每个格子上一个分数(非负整数)。棋盘第 1 格是唯一的起点,第 N 格是终点,游戏要求玩家控制一个乌龟棋子从起点出发走到终点。
![](http://icpc.upc.edu.cn/upload/image/20180321/20180321192354_84474.jpg)
很明显,用不同的爬行卡片使用顺序会使得最终游戏的得分不同,小明想要找到一种卡片使用顺序使得最终游戏得分最多。
现在,告诉你棋盘上每个格子的分数和所有的爬行卡片,你能告诉小明,他最多能得到多少分吗?
输入
输入每行中两个数之间用一个空格隔开。
第1行2个正整数N和M,分别表示棋盘格子数和爬行卡片数。
第2行N个非负整数,a1,a2,……,aN,其中ai表示棋盘第i个格子上的分数。
第3行M个整数,b1,b2,……,bM,表示M张爬行卡片上的数字。
输入数据保证到达终点时刚好用光M张爬行卡片,即
第1行2个正整数N和M,分别表示棋盘格子数和爬行卡片数。
第2行N个非负整数,a1,a2,……,aN,其中ai表示棋盘第i个格子上的分数。
第3行M个整数,b1,b2,……,bM,表示M张爬行卡片上的数字。
输入数据保证到达终点时刚好用光M张爬行卡片,即
输出
输出只有1行,1个整数,表示小明最多能得到的分数。
样例输入
9 5
6 10 14 2 8 8 18 5 17
1 3 1 2 1
样例输出
73
提示
小明使用爬行卡片顺序为1,1,3,1,2,得到的分数为6+10+14+8+18+17=73。注意,由于起点是1,所以自动获得第1格的分数6。
对于100%的数据有1≤N≤350,1≤M≤120,且4种爬行卡片,每种卡片的张数不会超过40;0≤ai≤100,1≤i≤N;1≤bi≤4,1≤i≤M。
思路:开思维数组记录当前四种卡牌已经使用的数量,dp即可。
#include<bits/stdc++.h> #include<queue> #include<cstdio> #include<iostream> #define REP(i, a, b) for(int i = (a); i <= (b); ++ i) #define REP(j, a, b) for(int j = (a); j <= (b); ++ j) #define PER(i, a, b) for(int i = (a); i >= (b); -- i) using namespace std; const int maxn=1e3+10; int p[350],tot,n,q[155],tmp,m; int dp[45][45][45][45]; inline int read() { char ch=getchar(); while(!(ch>='0'&&ch<='9'))ch=getchar(); int x=0; while(ch>='0'&&ch<='9'){x=x*10+(ch-'0');ch=getchar();} return x; } int main() { n=read(),m=read(); REP(i, 1, n)p[i]=read(); REP(i, 1, m)tmp=read(),q[tmp]++; dp[0][0][0][0]=p[1]; REP(i, 0, q[1]){ REP(j, 0, q[2]){ REP(h, 0, q[3]){ REP(k, 0, q[4]){ if(i+j+h+k==0)continue; dp[i][j][h][k]=0; if(i)dp[i][j][h][k]=max(dp[i][j][h][k],dp[i-1][j][h][k]); if(j)dp[i][j][h][k]=max(dp[i][j][h][k],dp[i][j-1][h][k]); if(h)dp[i][j][h][k]=max(dp[i][j][h][k],dp[i][j][h-1][k]); if(k)dp[i][j][h][k]=max(dp[i][j][h][k],dp[i][j][h][k-1]); dp[i][j][h][k]+=p[i+j*2+h*3+k*4+1]; } } } } cout<<dp[q[1]][q[2]][q[3]][q[4]]<<endl; }