题意:先去再回,不能吃重复的,获取最大值
分析:等价于两个人同时去,不能吃重复的
定义dp[i][j][k]表示从起点走k步,第一个人的横坐标是i,第二个人的横坐标是j的最最大值
这个题和bc上一个回文串的题是一样的
#include <cstdio> #include <cstring> #include <queue> #include <set> #include <map> #include <stack> #include <cstdlib> #include <algorithm> #include <vector> #include <cmath> using namespace std; typedef long long LL; typedef pair<int,int>pii; const int N=1e2+5; const int INF=0x3f3f3f3f; int n; LL dp[N][N][N*2]; LL a[N][N]; int dx[2]= {0,-1}; int dy[2]= {-1,0}; int main() { while(~scanf("%d",&n)) { for(int i=1; i<=n; ++i) for(int j=1; j<=n; ++j) scanf("%I64d",&a[i][j]); dp[1][1][0]=a[1][1]; for(int k=1; k<=2*n-2; ++k) { for(int i=1; i<=n; ++i) { for(int j=1; j<=n; ++j) { int x1=i,y1=k-i+2,x2=j,y2=k-j+2; if(y1<1||y1>n||y2<1||y2>n)continue; LL tmp=a[x1][y1]+a[x2][y2]; if(x1==x2&&y1==y2)tmp-=a[x1][y1]; bool flag=1; for(int k1=0; k1<2; ++k1) { for(int k2=0; k2<2; ++k2) { if(x1+dx[k1]<1||y1+dy[k1]<1)continue; if(x2+dx[k2]<1||y2+dy[k2]<1)continue; int k3=x1+dx[k1],k4=x2+dx[k2]; if(flag)dp[i][j][k]=dp[k3][k4][k-1]+tmp,flag=0; else dp[i][j][k]=max(dp[i][j][k],dp[k3][k4][k-1]+tmp); } } } } } printf("%I64d ",dp[n][n][2*n-2]); } return 0; }