题意:
- 有一种棋叫乌龟棋,棋盘只有一行,有N个格子,每个格子上有一个分数。
- 棋盘第1格是唯一的起点,第N格是唯一的终点,游戏要求玩家控制一个乌龟棋从起点出发走向终点。
- 有四种卡片,分别标有1,2,3,4。表示乌龟一次可以向前爬多少步,每爬到一个格子得到这个格子对应的分数。
-
给定各种卡片的数目,问最大的分数。
-
数据范围:$N\leq 350$。
思路:
- 设计状态$f(a,b,c,d)$表示a张1牌,b张2牌,c张3牌,d张4牌时的得分。
- 那么对于每张牌,只有选或者不选两种可能,那么有$f(a,b,c,d)=max(f(a,b,c,d),f(a-1,b,c,d)+num(r))$。
-
其中$r=a+2b+3c+4d$.
-
对于其他手牌也是一样的。
#include<bits/stdc++.h>
using namespace std;
const int maxn = 350;
int n, m;
int num[maxn], g[6];
int f[45][45][45][45];
int main()
{
scanf("%d%d", &n, &m);
for(int i = 1; i <= n; i++)
scanf("%d", &num[i]);
for(int i = 1, x; i <= m; i++)
{
scanf("%d", &x); g[x]++;
}
f[0][0][0][0] = num[1];
for(int a = 0; a <= g[1]; a++)
for(int b = 0; b <= g[2]; b++)
for(int c = 0; c <= g[3]; c++)
for(int d = 0; d <= g[4]; d++)
{
int r = 1+a+2*b+3*c+4*d;
if(a != 0)
f[a][b][c][d] = max(f[a][b][c][d], f[a-1][b][c][d] + num[r]);
if(b != 0)
f[a][b][c][d] = max(f[a][b][c][d], f[a][b-1][c][d] + num[r]);
if(c != 0)
f[a][b][c][d] = max(f[a][b][c][d], f[a][b][c-1][d] + num[r]);
if(d != 0)
f[a][b][c][d] = max(f[a][b][c][d], f[a][b][c][d-1] + num[r]);
}
cout << f[g[1]][g[2]][g[3]][g[4]] << endl;
return 0;
}