线性DP
作者:
橙外
,
2021-02-04 08:46:02
,
所有人可见
,
阅读 259
前言:一般的题目并不会题目直接呈现模型,我们需要找到某些性质将问题转化为线性DP
模型
让两种取法同时进行(它们所用的步数相同)
将总步数当做一维,然后两种路径的行标各当做一维
#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;
const int N = 15;
int n;
int w[N][N];
int f[N * 2][N][N];
// 第一维表示当前两次路径的行列坐标之和
// 第二维表示第一条路径的行标
// 第三维表示第二条路径的行标
int main()
{
scanf ("%d", &n);
int a, b, c;
while (scanf ("%d %d %d", &a, &b, &c), a || b || c) w[a][b] = c;
for (int k = 2; k <= n + n; k ++)
for (int i1 = 1; i1 <= n; i1 ++)
for (int i2 = 1; i2 <= n; i2 ++)
{
int j1 = k - i1, j2 = k - i2;
if (1 <= j1 && j1 <= n && 1 <= j2 && j2 <= n)
{
int t = w[i1][j1];
if (i1 != i2) t += w[i2][j2]; // 如果没有走到同一位置,那两个数都可以取
// 右右 右下 下右 下下
int &x = f[k][i1][i2];
x = max(x, f[k - 1][i1][i2] + t);
x = max(x, f[k - 1][i1][i2 - 1] + t);
x = max(x, f[k - 1][i1 - 1][i2] + t);
x = max(x, f[k - 1][i1 - 1][i2 - 1] + t);
}
}
printf ("%d", f[n + n][n][n]);
return 0;
}
与上一题做法类似,只是两条路径不能重合
那么两种路径的行标不能同时相等即可