传纸条

大力dp

一个正着跑,一个倒着跑,可以转换成两个正着跑

为了解决去重问题,我们规定第一条线不能越过第二条线,(没什么影响,不信画画图看看),这样就有一个显然的四维dp了,注意两个相等时要去一个

#include<iostream>
#include<cstdio>
#include<queue>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<set>
#include<map>
#include<vector>
#define maxn 101
#define int long long
#define SZJ signed
#include<time.h>
#define AK main
#define half (l+r)>>1
#define SDOI () 
using namespace std;
#define rep(i,a,b) for (int i=a;i<=b;++i) 
#define dep(i,a,b) for (int i=a;i>=b;i--)  
#define erpe (i,a) for (int i=head[a];i!=-1;i=e[i].next)
int n,m,dp[51][51][51][51],val[maxn][maxn];
inline int MAX(int a,int b,int c,int d) {return max(max(max(a,b),c),d);}
SZJ AK SDOI
{
	cin>>n>>m;
	rep(i,1,n) rep(j,1,m) cin>>val[i][j];
	rep(i,1,n) 
	rep(j,1,m) 
	rep(k,1,n) 
	rep(l,j,m) 
	{
		int tmp=val[i][j];
		if (i!=k||j!=l) tmp+=val[k][l];
		dp[i][j][k][l]=MAX(dp[i-1][j][k-1][l],dp[i-1][j][k][l-1],dp[i][j-1][k-1][l],dp[i][j-1][k][l-1]);
		dp[i][j][k][l]+=tmp;
	} 
	cout<<dp[n][m][n][m];
	return 0;
}
原文地址:https://www.cnblogs.com/bullshit/p/9907419.html