luogu 1004
动态规划。
设f[i][j][k]为行列之和为i,第一条路到第j行,第二条路到第k行的方案数。
考虑每条路的下一步可以向下或向右,于是状态转移方程就出来了。
f[i][j][k]=max(f[i-1][j][k],f[i-1][j-1][k],f[i-1][j-1][k-1],f[i-1][j][k-1])+a[j][i-j] (j=k)
f[i][j][k]=max(f[i-1][j][k],f[i-1][j-1][k],f[i-1][j-1][k-1],f[i-1][j][k-1])+a[j][i-j]+a[k][i-k] (j!=k)
#include"cstdio" #include"cctype" #include"algorithm" using namespace std; int n,a[10][10],f[21][10][10]; int main() { scanf("%d",&n); while(1) { int x,y,z; scanf("%d%d%d",&x,&y,&z); if(!x && !y && !z) break; a[x][y]=z; } for(int i=1;i<=2*n;i++) for(int j=1; j<=min(i-1,n); j++) for(int k=1; k<=min(i-1,n); k++) if(j==k) f[i][j][k]=max(max(f[i-1][j][k],f[i-1][j-1][k]),max(f[i-1][j-1][k-1],f[i-1][j][k-1]))+a[j][i-j]; else f[i][j][k]=max(max(f[i-1][j][k],f[i-1][j-1][k]),max(f[i-1][j-1][k-1],f[i-1][j][k-1]))+a[j][i-j]+a[k][i-k]; printf("%d\n",f[2*n][n][n]); return 0; }