正题
题目链接:https://www.luogu.com.cn/problem/P6855
题目大意
n∗mn*mn∗m的网格,每个格子有一个数,可以选择一个位置变为000。要求最小化最大权值和路径。
解题思路
考虑枚举哪个位置变为000,一个位置变为000后我们将路径分为两种路径,一种是经过该点的路径,一种是不经过该点的路径。
我们预处理出fi,jf_{i,j}fi,j表示(1,1)(1,1)(1,1)走到(i,j)(i,j)(i,j)的最大权和,gi,jg_{i,j}gi,j表示(i,j)(i,j)(i,j)走到(n,m)(n,m)(n,m)的最大权和。然后我们发现如果不走(x,y)(x,y)(x,y)这个位置,那么一会走(i,y)−>(i,y+1)(i,y)->(i,y+1)(i,y)−>(i,y+1)其中i<xi<xi<x或者(x,j)−>(x+1,j)(x,j)->(x+1,j)(x,j)−>(x+1,j)其中j<yj<yj<y。用ggg和fff计算这些走法的最大权值和即可。
时间复杂度O(nm)O(nm)O(nm)
codecodecode
#include<cstdio>
#include<cstring>
#include<algorithm>
#define ll long long
using namespace std;
const ll N=2100,XJQ=998244353;
ll n,m,ans,a[N][N],f[N][N],g[N][N],ar[N][N],br[N][N];
signed main()
{scanf("%lld%lld",&n,&m);for(ll i=1;i<=n;i++)for(ll j=1;j<=m;j++){scanf("%lld",&a[i][j]);f[i][j]=max(f[i-1][j],f[i][j-1])+a[i][j];}for(ll i=n;i>=1;i--)for(ll j=m;j>=1;j--){g[i][j]=max(g[i+1][j],g[i][j+1])+a[i][j];ar[i][j]=f[i][j]+g[i+1][j];br[i][j]=f[i][j]+g[i][j+1];}ans=1e18;for(ll i=1;i<=n;i++)for(ll j=1;j<=m;j++){ll z=max(f[i][j]+g[i][j]-2*a[i][j],max(ar[i][j-1],br[i-1][j]));ans=min(ans,z);if(j!=1)ar[i][j]=max(ar[i][j],ar[i][j-1]);if(i!=1)br[i][j]=max(br[i][j],br[i-1][j]);}printf("%lld",ans);
}