DP 数字三角形模型
简单来说举例就是方格只能往下走或者往右走的情况
dp数组 f[i][j]代表位置,从f[i-1]j或者f[i][j-1]左边过来
有一种比较有意思的情况即要走两遍然后之前走过的地方会受到影响
设有 N×N 的方格图,我们在其中的某些方格中填入正整数,而其它的方格中则放入数字0。如下图所示:
某人从图中的左上角 A 出发,可以向下行走,也可以向右行走,直到到达右下角的 B 点。
在走过的路上,他可以取走方格中的数(取走后的方格中将变为数字0)。
此人从 A 点到 B 点共走了两次,试找出两条这样的路径,使得取得的数字和为最大。
输入格式
第一行为一个整数N,表示 N×N 的方格图。
接下来的每行有三个整数,第一个为行号数,第二个为列号数,第三个为在该行、该列上所放的数。
行和列编号从 1
开始。
一行“0 0 0”表示结束。
输出格式
输出一个整数,表示两条路径上取得的最大的和。
数据范围
N≤10
对于这种情况,我们只需要增加一维,在f的第一位表示当前的步数(事实上,这是一种对于四维的优化,原来的f四维分别是两次路线的x,y坐标,因为x和y都可以通过k进行知一求一,故优化成三维)
f[k][i1][i2]
代码附上
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 15;
int w[N][N];
int f[N<<1][N][N];
int main()
{
int n;
cin>>n;
int a,b,c;
while(cin>>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(j1>=1&&j1<=n&&j2>=1&&j2<=n)
{
int &x=f[k][i1][i2];
int t=w[i1][j1];
if(i1!=i2){t+=w[i2][j2];}
x = max(x, f[k-1][i1-1][i2-1]+t);
x = max(x, f[k-1][i1-1][i2]+t);
x = max(x, f[k-1][i1][i2-1]+t);
x = max(x, f[k-1][i1][i2]+t);
}
}
}
}
cout<<f[n+n][n][n]<<endl;
return 0;
}