动态规划题解(数字三角形模型):
题面:
某人从图中的左上角 A 出发,可以向下行走,也可以向右行走,直到到达右下角的 B 点。
在走过的路上,他可以取走方格中的数(取走后的方格中将变为数字0)。
此人从 A 点到 B 点共走了两次,试找出两条这样的路径,使得取得的数字和为最大。
思路:
首先初步分析爆搜不行,大概率用dp来做,难点在于状态表示。类比只走一次,若只用
f[i][j]来表示状态, 则在状态转移时会遇到困难,限定了状态维数使得状态不能转移。
应该扩展状态维数使得状态转移顺利进行,即定义状态f[x1][y1][x2][y2]:第一条路径
走到(x1, y1)而第二条路径走到(x2,y2)时取走数之和的最大值,此时由于路径的最后一步
必定是向右或向下,便用分类最后一步来进行状态转移。
#include <bits/stdc++.h>
using namespace std;
int f[20][20][20][20], n, x, y, b;
int a[20][20];
int main() {
cin >> n;
while (cin >> x >> y >> b && x) {
a[x][y] = b;
}
for (int i = 1; i <= n; i++)
for (int j = 1; j <= n; j++)
for (int k = 1; k <= n; k++)
for (int l = 1; l <= n; l++) {
int &x = f[i][j][k][l];
x = max(max(f[i - 1][j][k - 1][l], f[i - 1][j][k][l - 1]), max(f[i][j - 1][k - 1][l], f[i][j - 1][k][l - 1]))
+ a[i][j];
if (i != k || j != l) x += a[k][l];
}
cout << f[n][n][n][n] << '\n';
return 0;
}