起初我是先dp了一遍,然后去除选择过的点,然后再dp一遍。就过了四个测试数据。这样果然有问题,可以写个数据试一下,这样走出来的不是最大的结果。去看讨论,有一个评论里面说这个叫多进程dp,涨知识了。
我先写了个四维数组的,超时。。。
#include <cstdio>
#include <cstring>
int G[100][100];
int dp[50][50][50][50];
int n,m;
int max(int a, int b)
{
return a > b ? a:b;
}
int main()
{
scanf("%d %d",&m,&n);
for(int i = 1; i <= n; ++i)
for(int j = 1; j <= m; ++j)
scanf("%d",&G[i][j]);
for(int i = 1; i <= n; ++i)
{
for(int j = 1; j <= m; ++j)
{
for(int p = 1; p <= n; ++p)
{
for(int q = 1; q <= m; ++q)
{
dp[i][j][p][q] = max(max(max(dp[i-1][j][p-1][q],dp[i-1][j][p][q-1]),dp[i][j-1][p-1][q]),dp[i][j-1][p][q-1]) + G[i][j] + G[p][q];
if(i == p && j == q)
dp[i][j][p][q] -= G[i][j];
}
}
}
}
printf("%d\n",dp[n][m][n][m]);
return 0;
}
然后写三维的,wa了几发就A了
#include <cstdio>
#include <cstring>
int G[201][201];
int dp[402][201][201];
int n,m;
int max(int a, int b)
{
return a > b ? a:b;
}
int main()
{
//freopen("in.txt","r",stdin);
scanf("%d %d",&m,&n);
for(int i = 1; i <= n; ++i)
for(int j = 1; j <= m; ++j)
scanf("%d",&G[i][j]);
for(int k = 1; k <= n+m; ++k)
{
for(int i = 1; i <= n && k-i >= 1; ++i)
{
for(int p = 1; p <= n && k-p >= 1; ++p)
{
dp[k][i][p] = max(max(max(dp[k-1][i-1][p],dp[k-1][i-1][p-1]),dp[k-1][i][p-1]),dp[k-1][i][p]) + G[i][k-i]+G[p][k-p];
if(i == p)
dp[k][i][p] -= G[i][k-i];
}
}
}
printf("%d\n",dp[n+m][n][n]);
return 0;
}