分土地问题(优化遍历问题)

本文探讨了一个土地划分问题,通过分析将原本时间复杂度为n^6的算法优化为log(n) f(n),其中f(n) < n^6/log(n)。借助二分查找和特定遍历策略,找到了确认最优划分的算法。详细分析和代码参考链接已提供。
摘要由CSDN通过智能技术生成

问题

题目描述
牛牛和 15 个朋友来玩打土豪分田地的游戏,牛牛决定让你来分田地,地主的田地可以看成是一个矩形,每个位置有一个价值。分割田地的方法是横竖各切三刀,分成 16 份,作为领导干部,牛牛总是会选择其中总价值最小的一份田地, 作为牛牛最好的朋友,你希望牛牛取得的田地的价值和尽可能大,你知道这个值最大可以是多少吗?
输入描述:
每个输入包含 1 个测试用例。每个测试用例的第一行包含两个整数 n 和 m(1 <= n, m <= 75),表示田地的大小,接下来的 n 行,每行包含 m 个 0-9 之间的数字,表示每块位置的价值。
输出描述:
输出一行表示牛牛所能取得的最大的价值。
示例1
输入
4 4
3332
3233
3332
2323
输出
2

问题来源:https://www.nowcoder.com/practice/fe30a13b5fb84b339cb6cb3f70dca699

问题分析

1°原始分析
在这个问题里面我们需要尝试不同的划分方案,然后得到所有划分方案下,最小区域的最大值。

如果按照这个朴素的思路来,我们需要采用时间复杂度为 n^6 的算法,在这个题目下,这个时间复杂度肯定是不能够被接受的。
(最后的解决方案不是我想出来的,我借鉴了牛客网的元气の悟空 同学分享的代码,我在他代码的基础上做了一点优化)

2°转换思路
我们换一种方式思考这个问题,首先我们可能得到这一整块土地的计算值(土地价值之后,后文将继续采用计算值这个说法)。我们最后的最小区域的最大值肯定是不大于 整块土地计算值的十六分之一。 然后我们可以尝试找到一个x,使得我们可以将土地划分为计算值不小于x的16区域,这个x是我们能找到的所有值中的最大值。

这个我们就将原来直觉上n^6时间复杂度的问题转化成 log(n) f(n)的问题。log(n) 为采用二分法查找x的时间复杂度,f(n)是确认x是否满足要求的时间复杂度,如果f(n) 不高于 n^6/log(n) ,那么这个算法就将好于暴力查找的方法。

3°选找到确认x是否满足要求的算法
这个还是需要采用遍历的方式检查,我们必须要至少遍历一个方向上的选择,比如行。但是在另外一个方向上我们可以不用遍历。
在确认了行方向的划分之后,我们引入一个结论

如果我们前k块划走的区域足够小的时候,那么这种情况下后面n-k块的最佳划分不会劣于前k块划走更多区域的时候的划分

我们需要在列方向上切三刀,如果第一刀切掉的计算值最小,那么剩下两刀切出来的最佳划分,应该至少不劣于第一刀切掉更多区域情况下的最佳划分。这一点很朴素,当然可能有点难理解,可以结合代码中 judge()放来理解。

代码

#include<stdio.h
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值