洛谷 P1541 乌龟棋

来源:互联网 发布:淘宝客服昵称怎么改 编辑:程序博客网 时间:2024/04/30 08:33

题目描述
乌龟棋的棋盘是一行N个格子,每个格子上一个分数(非负整数)。棋盘第1格是唯一的起点,第N格是终点,游戏要求玩家控制一个乌龟棋子从起点出发走到终点。
乌龟棋中M张爬行卡片,分成4种不同的类型(M张卡片中不一定包含所有4种类型的卡片,见样例),每种类型的卡片上分别标有1、2、3、4四个数字之一,表示使用这种卡片后,乌龟棋子将向前爬行相应的格子数。游戏中,玩家每次需要从所有的爬行卡片中选择一张之前没有使用过的爬行卡片,控制乌龟棋子前进相应的格子数,每张卡片只能使用一次。
游戏中,乌龟棋子自动获得起点格子的分数,并且在后续的爬行中每到达一个格子,就得到该格子相应的分数。玩家最终游戏得分就是乌龟棋子从起点到终点过程中到过的所有格子的分数总和。
很明显,用不同的爬行卡片使用顺序会使得最终游戏的得分不同,小明想要找到一种卡片使用顺序使得最终游戏得分最多。
现在,告诉你棋盘上每个格子的分数和所有的爬行卡片,你能告诉小明,他最多能得到多少分吗?


【题目分析】
动态规划


【代码】

#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>using namespace std;const int inf=0x3f3f3f3f;int dp[41][41][41][41];int cnt[5],a[400],n,m,x;inline int dfs(int i,int j,int k,int l){    if (dp[i][j][k][l]) return dp[i][j][k][l];    int ret=0;    if (1+i+j*2+k*3+l*4==n) return a[n];    if (1+i+j*2+k*3+l*4>n) return -inf;    if (i+1<=cnt[1]) ret=max(ret,dfs(i+1,j,k,l));    if (j+1<=cnt[2]) ret=max(ret,dfs(i,j+1,k,l));    if (k+1<=cnt[3]) ret=max(ret,dfs(i,j,k+1,l));    if (l+1<=cnt[4]) ret=max(ret,dfs(i,j,k,l+1));    return dp[i][j][k][l]=ret+a[1+i+j*2+k*3+l*4];}int main(){    scanf("%d%d",&n,&m);    for (int i=1;i<=n;++i) scanf("%d",&a[i]);    for (int i=1;i<=m;++i)    {        scanf("%d",&x);        cnt[x]++;    }    printf("%d\n",dfs(0,0,0,0));}
0 0
原创粉丝点击