思路:两条路径同时出发(两条路径同时考虑)。
不能分开走:分开考虑的话,第一条求解路径会影响第二条,因为求出第一条路径可能有多个选择。
//从最后一步开始分析
状态表示:dp[i1][i2][j1][j2]表示两条路径分别到达两个点的最大值,因为同时走,所以一定会有i1+i2=j1+j2,所以可以简化为三维dp[k][i1][i2],k为路径的横纵坐标之和。
状态计算:求某一状态的最大值可以转移成求上一状态的最大值再加上当前所求状态的方格数值,若当前状态的i1和i2相同,那么说明两条路径到达同一位置,因为方格数值不能重复取,所以方格数值只能加一次;若不同,就分别加两个位置的方格数值。
上一状态解释:(1.第一条路经从左边来第二条路径从上边来,2.第一条路经从左边来第二条路径从左边来,3.第一条路经从上边来第二条路径从上边来,4.第一条路经从上边来第二条路径从左边来)
#include<bits/stdc++.h>
using namespace std;
int dp[30][20][20];
int arr[20][20];
int main(){
int n;
cin>>n;
int x,y,a;
while(cin>>x>>y>>a,x||y||a){
arr[x][y]=a;
}
for(int k=1;k<=n+n;k++){
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
int i2=k-i,j2=k-j;
if(i2>0&&i2<=n&&j2>0&&j2<=n){
int t=arr[i][i2];
if(i!=j){
t=t+arr[j][j2];
}
int &x=dp[k][i][j];
x=max(x,dp[k-1][i][j]+t);
x=max(x,dp[k-1][i-1][j-1]+t);
x=max(x,dp[k-1][i-1][j]+t);
x=max(x,dp[k-1][i][j-1]+t);
}
}
}
}
cout<<dp[n+n][n][n];
return 0;
}