传纸条
题目大意:找两条不重复的路径使得相加最大
做法:两条路不重复dp
#include <cmath>
#include <cstdio>
#include <iostream>
using namespace std;
const int maxn = 51;
int n,m,a[maxn][maxn],dp[maxn][maxn][maxn][maxn];
int Max(int a,int b,int c,int d)
{
return max(max(a,b),max(c,d));
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
scanf("%d",&a[i][j]);
for(int i=1;i<=n;i++)
for(int j=1;j<m;j++)
for(int k=1;k<n;k++)
for(int l=j+1;l<=m;l++)
dp[i][j][k][l] = Max
(dp[i-1][j][k-1][l],dp[i][j-1][k-1][l]
,dp[i-1][j][k][l-1],dp[i][j-1][k][l-1])
+ a[i][j] + a[k][l];
printf("%d",dp[n][m-1][n-1][m]);
return 0;
}
精髓之处
for(int i=1;i<=n;i++)
for(int j=1;j<m;j++)
for(int k=1;k<n;k++)
for(int l=j+1;l<=m;l++)
他可以保证一定不会重复
说明:(i),(j)的终点是第(n)行,第(m-1)列,(k),(l)的终点是第(n-1)行,第(m)列,两个的终点不一样所以只需要保证中间过程没有重复就好。所以(j)只循环到(m-1),(k)只循环到(n-1),而要使得他们分开,只需要让他们的行不一样或列不一样即可,所以让(l)从(j+1)开始循环就能错开列,这样也就能保证两条路径并不会有重复。