#dp#洛谷 6855 「EZEC-4.5」走方格

题目


分析

考虑每个格子((i,j))获得的得分即为经过这个格子与不经过这个格子的答案
预处理出起点到每个点的最小得分和每个点到终点的最小得分,
那么经过这个格子的答案很好求,问题是不经过这个格子的答案,
也就是((1,1)->(i-x,j)->(i-x,j+1)->(n,m))或者是
((1,1)->(i,j-x)->(i+1,j-x)->(n,m)),这都是很好求的


代码

#include <cstdio>
#include <cctype>
#include <algorithm>
#define rr register
using namespace std;
const int N=2011; typedef long long lll;
int n,m,a[N][N]; lll ans,f1[N][N],f2[N][N],dp1[N][N],dp2[N][N];
inline signed iut(){
	rr int ans=0; rr char c=getchar();
	while (!isdigit(c)) c=getchar();
	while (isdigit(c)) ans=(ans<<3)+(ans<<1)+(c^48),c=getchar();
	return ans;
}
inline lll min(lll a,lll b){return a<b?a:b;}
inline lll max(lll a,lll b){return a>b?a:b;}
signed main(){
	n=iut(),m=iut(),ans=1e18;
	for (rr int i=1;i<=n;++i)
	for (rr int j=1;j<=m;++j)
	    a[i][j]=iut();
	for (rr int i=1;i<=n;++i)
	for (rr int j=1;j<=m;++j)
	    f1[i][j]=max(f1[i][j-1],f1[i-1][j])+a[i][j];
	for (rr int i=n;i>=1;--i)
	for (rr int j=m;j>=1;--j)
	    f2[i][j]=max(f2[i][j+1],f2[i+1][j])+a[i][j];
	for (rr int i=1;i<=n;++i)
	for (rr int j=1;j<=m;++j)
	    dp1[i][j]=max(dp1[i][j-1],f1[i][j]+f2[i+1][j]);
	for (rr int j=1;j<=m;++j)
	for (rr int i=1;i<=n;++i)
	    dp2[i][j]=max(dp2[i-1][j],f1[i][j]+f2[i][j+1]);
	for (rr int i=1;i<=n;++i)
	for (rr int j=1;j<=m;++j)
	    ans=min(ans,max(f1[i][j]+f2[i][j]-2*a[i][j],max(dp1[i][j-1],dp2[i-1][j])));
	return !printf("%lld",ans);
}
原文地址:https://www.cnblogs.com/Spare-No-Effort/p/13920872.html