做法一:
四维dp
分别枚举两个位置的坐标,状态转移只能从两个位置的上面和左边转移。
using namespace std;
#define int long long
#define endl '\n'
int a[10][10];
int f[10][10][10][10];
void solve()
{
int n;
cin>>n;
int x,y,b;
while(cin>>x,cin>>y,cin>>b && x!=0 && y!=0 && b!=0){
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 z=1;z<=n;z++){
f[i][j][k][z]=max({f[i-1][j][k-1][z],f[i][j-1][k][z-1],f[i-1][j][k][z-1],f[i][j-1][k-1][z]})+a[i][j];
if(i!=k && j!=z){
f[i][j][k][z]+=a[k][z];
}
}
}
}
}
cout<<f[n][n][n][n];
}//思维做法。
signed main()
{
int t;
t=1;
while(t--){
solve();
}
}
三维做法:
用一个总步数优化了一维,每个位置只需要保存一个坐标即可,因为总步数相同,所以可以知道这个点的具体坐标。
#include "bits/stdc++.h"
using namespace std;
#define int long long
#define endl '\n'
int a[10][10];
int f[20][10][10];
void solve()
{
int n;
cin>>n;
int x,y,b;
while(cin>>x,cin>>y,cin>>b && x!=0 && y!=0 && b!=0){
a[x][y]=b;
}
for (int i=1;i<=2*n;i++){
for (int j=1;j<=i &&j<=n;j++){
for (int k=1;k<=i && k<=n;k++){
f[i][j][k]=max({f[i-1][j][k],f[i-1][j-1][k],f[i-1][j][k-1],f[i-1][j-1][k-1]})+a[j][i-j]+a[k][i-k];
if(j==k){
f[i][j][k]-=a[j][i-j];
}
}
}
}
cout<<f[2*n][n][n];
}//思维做法。
signed main()
{
int t;
t=1;
while(t--){
solve();
}
}