【NOIP2008tj】传纸条

哈哈。。。
这题我竟然到现在才做(看见其同学早早地AC了,我十分gg)
暴力DP,设f[i][j][k][l]。
由于它是一来一回的而且不能有重叠,所以我们可以发现它一定是:
在这里插入图片描述
由于不能重叠,所以只有可能是上面的,而不可能↙

相交

在这里插入图片描述
上标:

#include<cstdio>
#define max(x,y) x=x>y ? x:y
using namespace std;
int n,m,a[52][52],f[52][52][52][52];

inline int read()
{
	int x=0; char c=getchar();
	while (c<'0' || c>'9') c=getchar();
	while (c>='0' && c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar();
	return x;
}

int main()
{
	freopen("czt.in","r",stdin);
//	freopen("czt.out","w",stdout);
	n=read(),m=read();
	for (int i=1;i<=n;i++)
		for (int j=1;j<=m;j++)
			a[i][j]=read();
	f[2][1][1][2]=a[1][2]+a[2][1];
	for (int i=1;i<=n;i++)
		for (int j=1;j<=m;j++)
			for (int k=1;k<=n;k++)
				for (int l=1;l<=m;l++)
					if (f[i][j][k][l])
					{
//						1:↓↓
						if (i<n) max(f[i+1][j][k+1][l],f[i][j][k][l]+a[i+1][j]+a[k+1][l]);
//						2:↓→
						if (i<n && l<m) max(f[i+1][j][k][l+1],f[i][j][k][l]+a[i+1][j]+a[k][l+1]);
//						3:→→
						if (l<m) max(f[i][j+1][k][l+1],f[i][j][k][l]+a[i][j+1]+a[k][l+1]);
//						4:→↓
						if ((k+1!=i && j+1!=l) || (i==n && l==m)) max(f[i][j+1][k+1][l],f[i][j][k][l]+a[i][j+1]+a[k+1][l]);
					}
	printf("%d
",f[n][m][n][m]);
	return 0;
}
转载需注明出处。
原文地址:https://www.cnblogs.com/jz929/p/11817729.html