乌龟棋
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;
}

 

 

【动规递推】【NOIP2010】乌龟棋 tortoise

相关文章: