题目链接:[点这儿].
题意:
![]()
一个菱形地图,每个格子有数字,问你从最上面一个格子走到最下面一个格子经过的数字加起来最大是多少,向下走的时候只能走下面相邻的两个格子.
解析:
简单的递推型动态规划,状态转移方程为:
dpi,j=arri,j+{max(j<arri−1.size?dpi−1,j:0,j−1<0?0:dpi−1,j−1)max(dpi−1,j,dpi−1,j+1)i<ni>=n
这种由上往下递推的动态规划,一般可以用滚动数组来优化内存空间.
代码:
#include <bits/stdc++.h>
using namespace std;
int main()
{
int T, K = 1;
for (scanf("%d", &T); T--; K++) {
int n, x;
scanf("%d", &n);
vector<vector<int> > arr(2), dp(2, vector<int>(n));
arr[0].push_back((scanf("%d", &x), x));
dp[0][0] = arr[0][0];
for (int i = 1; i < n; i++) {
for (int j = 0; j <= i; j++)
arr[i % 2].push_back((scanf("%d", &x), x));
for (int j = 0; j < arr[i % 2].size(); j++)
dp[i % 2][j] = arr[i % 2][j] +
max(j < arr[(i - 1) % 2].size() ? dp[(i - 1) % 2][j] : 0,
j - 1 < 0 ? 0 : dp[(i - 1) % 2][j - 1]);
arr[(i - 1) % 2].clear();
}
for (int i = n; i < 2 * n - 1; i++) {
for (int j = 2 * n - i - 1; j > 0; j--)
arr[i % 2].push_back((scanf("%d", &x), x));
for (int j = 0; j < arr[i % 2].size(); j++)
dp[i % 2][j] = arr[i % 2][j] + max(dp[(i - 1) % 2][j], dp[(i - 1) % 2][j + 1]);
arr[(i - 1) % 2].clear();
}
printf("Case %d: %d\n", K, dp[(2 * n - 2) % 2][0]);
}
return 0;
}