题目描述
解题思路
首先这是一个很明显的线性dp的题目,很容易发现规律
数据输入
我们用 h[ N ] 数组存储每一个格子的分数
用 cnt [ ],数组表示每一中卡片的数目
1,状态表示
因为这里一个有4种跳跃方式可以选择
f[ i ][ a ][ b ][ c ][ d ]表示 走到第 i 个格子的时候,1,2,3,4四种跳跃卡片分别用了,a,b,c,d张。
但是其实我们是可以去掉一维的,因为我们可以根据 1,2,3,4卡片的使用情况来推算我们当前到的位置 i = a + 2 * b + 3 * c + 4 * d
所以我们的状态表示为
f[ a ][ b ][ c ][ d ]表示 走到第 i = a + 2 * b + 3 * c + 4 * d 个格子的时候,1,2,3,4四种跳跃卡片分别用了,a,b,c,d张。
2,状态转移方程
f[ a ][ b ][ c ][ d ]
= max(f[ a - 1 ][ b ][ c ][ d ], f[ a ][ b - 1 ][ c ][ d ],f[ a ][ b ][ c - 1 ][ d ] ,f[ a ][ b ][ c ][ d - 1] ) + h[ j ]
3,初始化
根据题目信息 “游戏中,乌龟棋子自动获得起点格子的分数”
f[0][0][0][0] = h[0],因为价值大于等于 0 ,其他的格子都初始化为 0 即可。
4,填表顺序
咱们 4层for 从 a 到 d,从小到大即可
5,最终答案
f[ cnt[ 1 ] ] [ cnt[ 2 ] ] [ cnt[ 3 ] ] [ cnt[ 4 ] ]
6,AC代码
#include <iostream>
using namespace std;const int M = 45;
const int N = 360;int h[N] = { 0 };
int f[M][M][M][M] = { 0 };
int cnt[5] = { 0 };int n, m, sum;int main()
{cin >> n >> m;for (int i = 0; i < n; i++){cin >> h[i];}for (int i = 1; i <= m; i++){int x;cin >> x;cnt[x]++;}f[0][0][0][0] = h[0];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 j = a + b * 2 + c * 3 + d * 4;if (a - 1 >= 0){f[a][b][c][d] = max(f[a][b][c][d], f[a - 1][b][c][d] + h[j]);}if (b - 1 >= 0){f[a][b][c][d] = max(f[a][b][c][d], f[a][b - 1][c][d] + h[j]);}if (c - 1 >= 0){f[a][b][c][d] = max(f[a][b][c][d], f[a][b][c - 1][d] + h[j]);}if (d - 1 >= 0){f[a][b][c][d] = max(f[a][b][c][d], f[a][b][c][d - 1] + h[j]);}}}}}cout << f[cnt[1]][cnt[2]][cnt[3]][cnt[4]] << endl;return 0;
}