最平坦的路线题解

该题目描述了一个城市地图的旅行路径规划问题,要求找到从左上角到右下角的一条路径,使得经过的点的高度方差最小。输入包含地图的高度数据,输出为最小方差乘以(n+m-1)^2后的值。解决方案通过动态规划和枚举平均高度来计算最小方差,总时间复杂度为O(50nm(n+m))。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目描述

现有一个城市的地图,地图是一个n×mn\times mn×m的矩形,现在要在这个城市中旅行,旅行的起点左上角坐标为(1,1)(1,1)(1,1),终点右下角坐标为(n,m)(n,m)(n,m)。地图上记录了每一个点的高度,坐标为(x,y)(x,y)(x,y)的位置,高度为hx,yh_{x,y}hx,y。每次只能向右或向下,不能走出城市,只能在整数点转弯。请你计算出一条路线,使得经过的点的高度的方差最小。输出最小的方差乘(n+m−1)2(n+m-1)^2(n+m1)2后的值。

方差的定义:对于kkk个整数x1,x2,⋯ ,xkx_1,x_2,\cdots,x_kx1,x2,,xk,这kkk个数的方差为S2=(x1−x‾)2+(x2−x‾)2+⋯+(xk−x‾)2kS^2=\frac{(x_1-\overline{x})^2+(x_2-\overline{x})^2+\cdots+(x_k-\overline{x})^2}{k}S2=k(x1x)2+(x2x)2++(xkx)2,其中x‾\overline{x}x为这kkk个整数的平均值,即x‾=x1+x2+⋯+xkk\overline{x}=\frac{x_1+x_2+\cdots+x_k}{k}x=kx1+x2++xk

输入格式

第一行输入n,mn,mn,m
下面nnn行,每行mmm个数,第iii行第jjj列为hi,jh_{i,j}hi,j

输出格式

输出最小的方差乘(n+m−1)2(n+m-1)^2(n+m1)2后的值

样例输入
2 2
1 2
3 4

样例输出

14

数据范围

对于30%30\%30%的数据,1≤n,m≤101\leq n,m\leq 101n,m10
对于50%50\%50%的数据,1≤n,m≤201\leq n,m\leq 201n,m20
对于100%100\%100%的数据,1≤n,m≤50,0≤hx,y≤501\leq n,m\leq 50,0\leq h_{x,y}\leq 501n,m50,0hx,y50


题解

可以看出要经过的点的数量为n+m−1n+m-1n+m1,为方便表述,令k=n+m−1k=n+m-1k=n+m1

数据范围比较小,平均数又不好处理,我们可以考虑枚举平均数。因为0≤x‾≤500\leq \overline{x} \leq 500x50,所以0≤k⋅x‾≤50k0\leq k\cdot\overline{x} \leq 50k0kx50k,且k⋅x‾k\cdot\overline{x}kx为整数。于是我们就可以枚举k⋅x‾k\cdot\overline{x}kx,再计算最大值。

将要求的式子拆一下,k2×S2=k2×(x1−x‾)2+(x2−x‾)2+⋯+(xk−x‾)2k=k((∑xi2)−2x‾(∑xi)+kx‾2)k^2\times S^2=k^2\times\frac{(x_1-\overline{x})^2+(x_2-\overline{x})^2+\cdots+(x_k-\overline{x})^2}{k}=k((\sum x_i^2)-2\overline{x}(\sum x_i)+k\overline{x}^2)k2×S2=k2×k(x1x)2+(x2x)2++(xkx)2=k((xi2)2x(xi)+kx2),在x‾\overline{x}x一定的情况下,xix_ixi的贡献为k(xi2−2x‾xi)=kxi2−2kx‾xik(x_i^2-2\overline{x}x_i)=kx_i^2-2k\overline{x}x_ik(xi22xxi)=kxi22kxxi

设当前枚举的k⋅x‾k\cdot\overline{x}kx值为ttt,设fi,jf_{i,j}fi,j表示从(1,1)(1,1)(1,1)(i,j)(i,j)(i,j)的最小的贡献,则可以列出转移式
fi,j=min⁡(fi−1,j,fi,j−1)+k⋅hi,j2+2t⋅hi,jf_{i,j}=\min(f_{i-1,j},f_{i,j-1})+k\cdot h_{i,j}^2+2t\cdot h_{i,j}fi,j=min(fi1,j,fi,j1)+khi,j2+2thi,j

那么答案为对于每一个tttfn,m+t2f_{n,m}+t^2fn,m+t2的最小值。

那如果这kkk个数的平均值乘kkkttt不相等怎么办,不就多算了几种情况吗?

会多一些情况,但不影响答案。设t=kx‾+a(a≠0)t=k\overline{x}+a(a\neq0)t=kx+a(a=0)
此次计算的答案:k(∑xi2)−2t(∑xi)+t2=k(∑xi2)−2(kx‾+a)(kx‾)+(kx‾+a)2k(\sum x_i^2)-2t(\sum x_i)+t^2=k(\sum x_i^2)-2(k\overline{x}+a)(k\overline{x})+(k\overline{x}+a)^2k(xi2)2t(xi)+t2=k(xi2)2(kx+a)(kx)+(kx+a)2

实际上的答案:k(∑xi2)−2kx‾(∑xi)+k2x‾2=k(∑xi2)−2(kx‾)2+k2x‾2k(\sum x_i^2)-2k\overline{x}(\sum x_i)+k^2\overline{x}^2=k(\sum x_i^2)-2(k\overline{x})^2+k^2\overline{x}^2k(xi2)2kx(xi)+k2x2=k(xi2)2(kx)2+k2x2

上下做差得−2akx‾+2akx‾+a2=a2>0-2ak\overline{x}+2ak\overline{x}+a^2=a^2>02akx+2akx+a2=a2>0,所以当t≠kx‾t\neq k\overline{x}t=kx时,得出的答案会更大,而这个答案一定会被t=kx‾t=k\overline{x}t=kx时的答案覆盖,所以这是可行的。

枚举tttO(50(n+m))O(50(n+m))O(50(n+m)),每次DP都是O(nm)O(nm)O(nm),所以总时间复杂度为O(50nm(n+m))O(50nm(n+m))O(50nm(n+m))

code

#include<bits/stdc++.h>
using namespace std;
int n,m,k;
long long ans=1e18,a[55][55],f[55][55];
int main()
{
	scanf("%d%d",&n,&m);k=n+m-1;
	for(int i=1;i<=n;i++){
		for(int j=1;j<=m;j++){
			scanf("%lld",&a[i][j]);
		}
	}
	for(int o=0;o<=5000;o++){
		f[1][1]=a[1][1]*a[1][1]*k-2*a[1][1]*o;
		for(int i=1;i<=n;i++){
			for(int j=1;j<=m;j++){
				if(i!=1||j!=1) f[i][j]=1e18;
				if(i>1) f[i][j]=min(f[i][j],f[i-1][j]+a[i][j]*a[i][j]*k-2*a[i][j]*o);
				if(j>1) f[i][j]=min(f[i][j],f[i][j-1]+a[i][j]*a[i][j]*k-2*a[i][j]*o);
			}
		}
		ans=min(ans,f[n][m]+o*o);
	}
	printf("%lld",ans);
	return 0;
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值