NOIP提高组2010 乌龟棋

小明过生日的时候,爸爸送给他一副乌龟棋当作礼物。

乌龟棋的棋盘是一行N个格子,每个格子上一个分数(非负整数)。棋盘第1格是唯一的起点,第N格是终点,游戏要求玩家控制一个乌龟棋子从起点出发走到终点。

乌龟棋中M张爬行卡片,分成4种不同的类型(M张卡片中不一定包含所有4种类型的卡片,见样例),每种类型的卡片上分别标有1、2、3、4四个数字之一,表示使用这种卡片后,乌龟棋子将向前爬行相应的格子数。游戏中,玩家每次需要从所有的爬行卡片中选择一张之前没有使用过的爬行卡片,控制乌龟棋子前进相应的格子数,每张卡片只能使用一次。

游戏中,乌龟棋子自动获得起点格子的分数,并且在后续的爬行中每到达一个格子,就得到该格子相应的分数。玩家最终游戏得分就是乌龟棋子从起点到终点过程中到过的所有格子的分数总和。

很明显,用不同的爬行卡片使用顺序会使得最终游戏的得分不同,小明想要找到一种卡片使用顺序使得最终游戏得分最多。

现在,告诉你棋盘上每个格子的分数和所有的爬行卡片,你能告诉小明,他最多能得到多少分吗

Input

9 5
6 10 14 2 8 8 18 5 17
1 3 1 2 1

Output

73


提示

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

https://vijos.org/p/1775

F[ 0 ][ 0 ][ 0 ][ 0 ] = Q[1]  初始位置

用四位数组F[ I ][ J ][ K ][ L ]来分别表示1 , 2 , 3 , 4的张数,Q来表示使用 i , j , k, l 张时可以得到的分数,  

-->  F[ I ][ J ][ K ][ L ] = max{a > 0, F[ I-1 ][ J ][ K ][ L ] + Q[ a*1+b*2+c*3+d*4  + 1]  //  +1 是因为从第一个格子开始

 

                                                 b > 0,F[ I ][ J-1 ][ K ][ L ]+ Q[ a*1+b*2+c*3+d*4 + 1 ] 

                                                 c > 0 , F[ I ][ J ][ K-1 ][ L ] + Q[ a*1+b*2+c*3+d*4  + 1] 

                                                d  > 0,F[ I ][ J ][ K ][ L-1 ]+ Q[ a*1+b*2+c*3+d*4 + 1

下面代码来之    jiangzh7 

#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <map>
#include <queue>
#include <algorithm>
using namespace std;
int n,k,m;
const int maxn = 0x3f3f3f3f;
int num[5];
int a[400];
int f[100][100][100][100];
int main()
{
    while(~scanf("%d%d",&n,&m))
    {
        memset(f,0,sizeof(f));
        memset(a,0,sizeof(a));
        for(int i = 1; i <= n; i++)
            scanf("%d",&a[i]);


        for(int i = 1; i <= m; i++)
        {
            int a;
            scanf("%d",&a);
            num[a] ++ ;
        }
        f[0][0][0][0] = a[1];
        for(int i = 0; i <= num[1]; i++)
            for(int j = 0; j <= num[2]; j++)
                for(int k = 0; k <= num[3]; k++)
                    for(int l = 0; l <= num[4]; l++)
                    {
                         if(i >= 1)
                            f[i][j][k][l] = max(f[i][j][k][l], f[i-1][j][k][l] + a[1 + i + 2*j + 3*k + 4*l]);
                         if(j >= 1)
                            f[i][j][k][l] = max(f[i][j][k][l], f[i][j-1][k][l] + a[1 + i + 2*j + 3*k + 4*l]);
                         if(k >= 1)
                            f[i][j][k][l] = max(f[i][j][k][l], f[i][j][k-1][l] + a[1 + i + 2*j + 3*k + 4*l]);
                         if(l >= 1)
                            f[i][j][k][l] = max(f[i][j][k][l], f[i][j][k][l-1] + a[1 + i + 2*j + 3*k + 4*l]);
                    }
        printf("%d
",f[num[1]][num[2]][num[3]][num[4]]);
    }
    return 0;
}

  

原文地址:https://www.cnblogs.com/Przz/p/5409823.html