【洛谷P6855】走方格

题目

题目链接:https://www.luogu.com.cn/problem/P6855
\(n\times m\) 的方格矩阵,小 A 从 \((1,1)\) 出发到 \((n,m)\) ,只能向下或向右走,获得的分数为他经过方格的权值之和。

已知每个方格 $(i,j) $的权值 \(a_{i,j}\),你可以将其中任意一个方格上的权值变为 \(0\),求变化后小 A 最多能获得分数的最小值

思路

首先我们发现,改动为 \(0\) 的格子一定在最长路径上,否则改了这个格子最长路径长度没变,显然不是最优解。

因为从点 \((1,1)\)\((n,m)\) 且只可以往下或往右的任意一条路径长度都为 \(n+m-1\),所以答案只可能是修改这 \(n+m-1\) 个点中的一个。

我们先求出 \(f[i][j]\) 表示点 \((1,1)\)\((i,j)\) 的最长路径长度,\(g[i][j]\) 表示点 \((n,m)\)\(i,j\) 的最长路径长度,然后枚举最长路径上的每一个点 \((x,y)\),需要求出将这个点权值设为 \(0\) 之后从 \((1,1)\)\((n,m)\) 的最长路径。

经过点 \((x,y)\) 的最长路径长度为 \(f[x][y]+g[x][y]-2\times a[x][y]\),对于不经过点 \((x,y)\) 的点,我们枚举这条路径从第 \(x\) 行走向第 \(x+1\) 行是在哪一列,设为 \(k\),那么设 \(h[k]\) 表示这条路径从第 \(x\) 行到第 \(x+1\) 行走的是第 \(k\) 列,且不经过 \((x,y)\) 的最长路径。

那么有

\[h[k]=\left\{\begin{matrix}-\infty\ (k=y)\\ \max(h[k-1],f[x-1][k])+a[x][k]\ (k\neq y)\end{matrix}\right. \]

此时从第 \(k\) 列下去的路径长度最大值就是 \(h[k]+g[x+1][k]\)

所以将 \((x,y)\) 赋值为 \(0\),路径长度最大值就是

\[\max(h[k]+g[x+1][k],f[x][y]+g[x][y]-2\times a[x][y]) \]

在所有答案中取 \(\min\) 即可。

由于我们只尝试将 \(n+m-1\) 个点赋值为 \(0\),每个点计算复杂度是 \(O(n)\),总时间复杂度 \(O(n^2)\)

代码

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;

const int N=2010;
const ll Inf=1000000000000000000LL;
int n,m;
ll ans,f[N][N],g[N][N],h[N],a[N][N];

int main()
{
	memset(f,0xcf,sizeof(f));
	memset(g,0xcf,sizeof(g));
	scanf("%d%d",&n,&m);
	ans=Inf; f[0][1]=f[1][0]=g[n+1][m]=g[n][m+1]=0;
	for (int i=1;i<=n;i++)
		for (int 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 (int i=n;i>=1;i--)
		for (int j=m;j>=1;j--)
			g[i][j]=max(g[i+1][j],g[i][j+1])+a[i][j];
	for (int x=n,y=m;x!=1 || y!=1;)
	{
		ll maxn=0;
		h[0]=-Inf;
		for (int i=1;i<=m;i++)
		{
			if (i==y) h[i]=-Inf;
			else
			{
				h[i]=max(h[i-1],f[x-1][i])+a[x][i];
				maxn=max(maxn,h[i]+g[x+1][i]);
			}
		}
		maxn=max(maxn,f[x][y]+g[x][y]-a[x][y]*2LL);
		ans=min(ans,maxn);
		
		if (x==1) y--;
		else if (y==1) x--;
		else if (f[x-1][y]>f[x][y-1]) x--;
		else y--;
	}
	printf("%lld",min(ans,f[n][m]-a[1][1]));
	return 0;
}
posted @ 2020-10-04 22:35  stoorz  阅读(251)  评论(0编辑  收藏  举报