样例输入:
8
2 3 13
2 6 6
3 5 7
4 4 14
5 2 21
5 6 4
6 3 15
7 2 14
0 0 0
样例输出:
67
思路:
将两次路径合成一个dp数组,dp数组里有三维参数,用k表示i+j之和,用i1表示第一次走的路径的横坐标,i2表示第二次走的路径的横坐标,根据横坐标和k可以计算出各自的j
更新dp末状态:
每一次前进一步相当于对k++,再由不同的i可推算出相应的坐标,若是两次路径的坐标相同则只加一次,若是不同则两个坐标上的权重都加。
末状态分为四种:
代码实现:
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
const int N=15;
int dp[2*N][N][N];
int map[N][N];
int n;
int main(){
cin>>n;
int a,b,c;
while(cin>>a>>b>>c,a||b||c) map[a][b]=c;
for(int k=2;k<=2*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 t=map[i1][j1];
if(i1!=i2) t+=map[i2][j2];
int &x=dp[k][i1][i2];
x=max(x,dp[k-1][i1-1][i2-1]+t);
x=max(x,dp[k-1][i1-1][i2]+t);
x=max(x,dp[k-1][i1][i2-1]+t);
x=max(x,dp[k-1][i1][i2]+t);
}
}
}
}
cout<<dp[n+n][n][n]<<endl;
return 0;
}