Luogu P1541 乌龟棋

Description:

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

Analysis:

f[a][b][c][d] :=使用了a张1,b张2,c张3,d张4的最大得分
初始化,f[0][0][0][0] = s[1]

Code

#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
const int MAX_P = 41,MAX_N = 400;
int cnt[5],s[MAX_N],f[MAX_P][MAX_P][MAX_P][MAX_P],n,m;
int main()
{
	scanf("%d%d",&n,&m);
	for(int i = 1;i <= n;++i)
	{
		scanf("%d",&s[i]);
	}
	for(int i = 1;i <= m;++i)
	{
		scanf("%d",&cnt[0]);
		cnt[cnt[0]]++;
	}
	f[0][0][0][0] = s[1];
	for(int a = 0;a <= cnt[1];++a)
	{
		for(int b = 0;b <= cnt[2];++b)
		{
			for(int c = 0;c <= cnt[3];++c)
			{
				for(int d = 0;d <= cnt[4];++d)
				{
					int t = 1 + a + 2*b + 3*c + 4*d;
					if(a) f[a][b][c][d] = max(f[a][b][c][d],f[a-1][b][c][d] + s[t]);
					if(b) f[a][b][c][d] = max(f[a][b][c][d],f[a][b-1][c][d] + s[t]);
					if(c) f[a][b][c][d] = max(f[a][b][c][d],f[a][b][c-1][d] + s[t]);
					if(d) f[a][b][c][d] = max(f[a][b][c][d],f[a][b][c][d-1] + s[t]);
				}
			}
		}
	}
	printf("%d
",f[cnt[1]][cnt[2]][cnt[3]][cnt[4]]);
	return 0;
}

一开始的sb做法.......炸了

#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
const int MAX_N = 200,MAX_M = 100,MAX_P = 20;
int cnt[5],a[MAX_N],f[MAX_N][MAX_M][MAX_P][MAX_P][MAX_P],n,m; 
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",&cnt[0]);
		cnt[cnt[0]]++;
	}

	for(int j = 1;j <= m;++j)
	{
		for(int k = 0;k <= cnt[1];++k)
		{
			for(int l = 0; l <= cnt[2];++l)
			{
				for(int r = 0;r <= cnt[3];++r)
				{
					f[1][j][k][l][r] = a[1];
				}
			}
		}
	}

	for(int i = 2;i <= n;++i)
	{
		for(int j = 1;j <= m;++j)
		{
			for(int k = 0;k <= cnt[1] && k <= j;++k)
			{
				for(int l = 0; l <= cnt[2] && k + l <= j;++l)
				{
					for(int r = 0;r <= cnt[3] && k + l + r <= j;++r)
					{
						f[i][j][k][l][r] = max(f[i-1][j-1][k-1][l][r],max(f[i-2][j-1][k][l-1][r],max(f[i-3][j-1][k][l][r-1],f[i-4][j-1][k][l][r]))) + a[i];
					}
				}
			}
		}
	}
	int ans = 0;
	for(int k = 0;k <= cnt[1];++k)
	{
		for(int l = 0;l <= cnt[2];++l)
		{
			for(int r = 0;r <= cnt[3];++r)
			{
				ans = max(ans,f[n][m][k][l][r]);
			}
		}
	}
	printf("%d
",ans);
    return 0;
}
岂能尽如人意,但求无愧我心
原文地址:https://www.cnblogs.com/Zforw/p/11303997.html