題目鏈接:https://www.luogu.com.cn/problem/P1004
考慮讓兩個人同時走,設計狀態則直接設f[i][j][k][m],表示第一個人走到(i,j),第二個人走到(k,m)時所取數的最大值。
當(i,j)==(k,m)時,即兩個人走到同一個點,則這個點其實在第二遍的時候已經爲0,所以這個點的貢獻只是一次。
則有轉移方程:
f[i][j][k][m]=max(f[i-1][j][k-1][m],max(f[i-1][j][k][m-1],max(f[i][j-1][k-1][m],f[i][j-1][k][m-1]))); if(i==k&&j==m) f[i][j][k][m]+=g[i][j]; else f[i][j][k][m]+=g[i][j]+g[k][m];
並且最後一維m不需要枚舉,用i+j-k計算出來即可。(應該只能這樣做)
AC代碼:
1 #include<cstdio> 2 #include<iostream> 3 #include<cstring> 4 using namespace std; 5 const int N=10; 6 int n,res; 7 int a,b,c; 8 int g[N][N],s[N],f[N][N][N][N]; 9 int main(){ 10 scanf("%d",&n); 11 while(scanf("%d%d%d",&a,&b,&c)&&a!=0) g[a][b]=c; 12 for(int i=1;i<=n;i++) 13 for(int j=1;j<=n;j++) 14 for(int k=1;k<=n;k++){ 15 int m=i+j-k; 16 if(m<0) continue; 17 f[i][j][k][m]=max(f[i-1][j][k-1][m],max(f[i-1][j][k][m-1],max(f[i][j-1][k-1][m],f[i][j-1][k][m-1]))); 18 if(i==k&&j==m) f[i][j][k][m]+=g[i][j]; 19 else f[i][j][k][m]+=g[i][j]+g[k][m]; 20 } 21 printf("%d",f[n][n][n][n]); 22 return 0; 23 }