乌龟棋
tortoise
题目描述
小明过生日的时候,爸爸送给他一副乌龟棋当作礼物。
乌龟棋的棋盘是一行N 个格子,每个格子上一个分数(非负整数)。棋盘第1 格是唯一的起点,第N 格是终点,游戏要求玩家控制一个乌龟棋子从起点出发走到终点。
| …… |
| 1 | 2 | 3 | 4 | 5 | …… | N |
输入格式
输入文件的每行中两个数之间用一个空格隔开。
第1 行2 个正整数N 和M,分别表示棋盘格子数和爬行卡片数。
第2 行N 个非负整数,a1, a2, ……, aN,其中ai 表示棋盘第i 个格子上的分数。
第3 行M 个整数,b1,b2, ……, bM,表示M 张爬行卡片上的数字。
输入数据保证到达终点时刚好用光M 张爬行卡片,即N−;;1=Σb_i (1<=i<=M)
输出格式
输出只有1 行,1 个整数,表示小明最多能得到的分数。
【输入输出样例1】
tortoise.in
9 5
6 10 14 2 8 8 18 5 17
1 3 1 2 1
tortoise.out
73
【输入输出样例2】
tortoise.in
13 8
4 96 10 64 55 13 94 53 5 24 89 8 30
1 1 1 1 1 2 4 1
tortoise.out
455
显然这是一道动规的题目,状态设计可以用四维f[a][b][c][d]来维护,表示f["1"的张数]["2"的张数]["3"的张数]["4"的张数]
方程就很显然了
f[a][b][c][d]=max{(a>0) f[a-1][b][c][d]+a[a*1+b*2+c*3+d*4],
(b>0) f[a][b-1][c][d]+a[a*1+b*2+c*3+d*4],
(c>0) f[a][b][c-1][d]+a[a*1+b*2+c*3+d*4],
(d>0) f[a][b][c][d-1]+a[a*1+b*2+c*3+d*4]}
当然,由于第一个点自动得分,所以f[0][0][0][0]=a[1](这也是为什么我们只用计算每一部终点的得分,可以确保起点已经计算)
C++ Code
/*
C++ Code
http://oijzh.cnblogs.com
*/
#include<cstdio>
#define MAXN 400
int n,m,a[MAXN],sum[5];
int f[50][50][50][50];
int main()
{
freopen("tortoise.in","r",stdin);
freopen("tortoise.out","w",stdout);
scanf("%d%d",&n,&m);
int i,j,k,t,x;
for(i=1;i<=n;i++) scanf("%d",&a[i]);
for(i=1;i<=m;i++) {scanf("%d",&x);sum[x]++;}
f[0][0][0][0]=a[1];
for(i=0;i<=sum[1];i++)
for(j=0;j<=sum[2];j++)
for(k=0;k<=sum[3];k++)
for(t=0;t<=sum[4];t++)
{
if(i>=1)f[i][j][k][t]>?=f[i-1][j][k][t]+a[1+i*1+j*2+k*3+t*4];
if(j>=1)f[i][j][k][t]>?=f[i][j-1][k][t]+a[1+i*1+j*2+k*3+t*4];
if(k>=1)f[i][j][k][t]>?=f[i][j][k-1][t]+a[1+i*1+j*2+k*3+t*4];
if(t>=1)f[i][j][k][t]>?=f[i][j][k][t-1]+a[1+i*1+j*2+k*3+t*4];
}
printf("%d",f[sum[1]][sum[2]][sum[3]][sum[4]]);
return 0;
}