当前位置: 首页 > news >正文

有什么做兼职的好网站网架生产企业

有什么做兼职的好网站,网架生产企业,计算机应用技术网站建设,wordpress 添加插件大家好,不同的时间,相同的地点,时隔多日我们又见面了。继上次的二分算法后,我们这次要来学习的是二分答案了。这个部分相较于前面的二分算法难度有相当的提升,希望大家有所准备。虽然难度增加了,但是博主还…

大家好,不同的时间,相同的地点,时隔多日我们又见面了。继上次的二分算法后,我们这次要来学习的是二分答案了。这个部分相较于前面的二分算法难度有相当的提升,希望大家有所准备。虽然难度增加了,但是博主还是会将其讲明白讲清楚的

let's go!

前言

二分算法虽然简单但是它是很重要的,在某些题目当中,我们以后还会遇到,希望大家能够有所重视。

1.二分答案

二分答案具体为:二分答案 + 判断

当做算法题的时候,如果遇到最大值最小以及最小值最大的问题,就可以思考着去使用二分答案来解决了。二分答案可以帮助解决绝大多数这类的问题,如果解空间在从小到大的变化过程中,判断答案的结果出现二段性,此时我们就可以去使用二分,去二分这个解空间,通过判断来找出最优解。

可能大家看这个概念还是比较抽象,跟着博主做完下面三道题后大家就会明白了。

2.题目

P2440 木材加工 - 洛谷

P1873 [COCI 2011/2012 #5] EKO / 砍树 - 洛谷

P2678 [NOIP 2015 提高组] 跳石头 - 洛谷

大家可以先行做一下这几道题,然后再看博主的思路。

3.木材加工

题目展示:

思路分析:

这道题可以说的上是二分答案的一道模版题目了,大家好好理解一下这道题:

大家看完题目后,应该有对题目有些理解了,那么我再来梳理一下这个题目吧。

这个题目会给出木头n个需要切割出来的木头段数k,然后会给出n个木头的长度a[i]

我们思考一下也就知道,如果我们将木头切割成1cm的木头(最短)那么我们肯定是可以满足题目要求的段数,但是问题来了我们切割成1cm的小段不是能够切割出来的最长?

那么我们一种暴力的解法就是:

暴力解法思路:

枚举切割的长度从1到最长的木头,然后开始通过这个切割长度x来计算段数(t) t = a[i] / x

通过将段数最后计算出来的和拿来和要求的k来比较,如果总和大于k就可以算是待正确答案。

这样的话,我们可以将切割长度从最长的木头长度往1开始减少的枚举,这样当第一次出现大于k的情况那个切割长度就是我们需要的答案

对于这个思路大家有兴趣可以去实现一下,难度不大。

但是会出现超时的情况,我们就得用到二分答案的算法来解决这道题了。

二分答案思路:

如果我们所要的切割长度为ans,我们无非就是要在0~maxlen中找到这个答案ans

------------------------------------------
[0                ans              maxlen]
------------------------------------------

当枚举的切割长度x在ans的左边时,切割出来的段数 t >= k

当枚举的切割长度x在ans的右边时,切割出来的段数 t < k

所以这道题答案是具有二段性的,所以可以通过二分来解决

left          mid             right
calc(mid)计算当前切割长度能切多少段 
calc(mid) >= k  left = mid;
calc(mid) <  k  right = mid - 1;

这时候后面的一个代码实现就变得简单很多了

代码实现:

#include <iostream>
using namespace std;
const int N = 1e5 + 10;
typedef long long LL;
LL n, k;
LL a[N];LL calc(LL x)
{//通过切割长度x计算切出的数量LL ret = 0;for (int i = 1; i <= n; i++){ret += a[i] / x;	}return ret;
}int main()
{cin >> n >> k;LL r = 0;for (int i = 1; i <= n; i++){cin >> a[i];r = max(r, a[i]);}LL l = 0;while(l < r){LL mid = (l + r + 1) / 2;if (calc(mid) >= k) l = mid;else r = mid - 1;}cout << l << endl;return 0;
}

4.砍树

题目展示:

思路分析:

这道题跟前面的那道题是很相似的大家看完前一道题后做这道题应该难度不会很大了。

但是现在还是跟着博主的思路开始分析一下这道题吧:

这道题给出了这一排树的数目n所需的木材m两个数,接着给出了每棵树的高度a[i]

我们需要找到一个合适的高度既能够保护树,也能满足需求的木材

那么我们的高度就只能是在0到最高的树的高度来枚举

如果我们最后答案的树高为ans

----------------------------------------------

[0                   ans                 maxh]

----------------------------------------------

当h小于ans时,获得的木材 l >= m

当h大于ans时,获得的木材 l < m

答案是具有二段性的,去思考使用二分答案来解决

left                 mid                 right

当枚举树高为mid,calc(mid)为此时获得的木材
当calc(mid) >= m时,l = mid
当calc(mid) < m时,r = mid - 1

代码实现:

#include <iostream>
using namespace std;
const int N = 1e6 + 10;
typedef long long LL;
LL n, m;
LL a[N];LL calc(LL x)
{// 计算出x树高的时候,切割出来的木材数LL ret = 0;for (int i = 1; i <= n; i++){if (a[i] >= x) ret += a[i] - x;}return ret;
}
int main()
{cin >> n >> m;LL r = 0;for (int i = 1; i <= n; i++){cin >> a[i];r = max(r, a[i]);}LL l = 0;while(l < r){LL mid = (l + r + 1) / 2;if (calc(mid) >= m) l = mid;else r = mid - 1;}cout << l << endl;return 0;
}

5.跳石头

题目展示:

思路分析:

这道题题目可能刚看会有些不明白是怎么一回事,可以仔细看看

现在跟着博主的思路开始分析一下这道题目吧:

题目中会给出起点到终点的距离L起点和终点之间的岩石数N,以及组委会至多移走的岩石数M

然后会给出N个值a[i]每个值a[i]代表第i个石头距离起点的距离

题目要我们求的是什么呢?让我们求最短跳跃距离的最大值

这是不是就是很符合我们二分答案吗?

那么什么叫做最短跳跃距离的最大值呢?

由于移走石头后选手会进行每块石头之间的跳跃,在所有跳跃中,会出现一个最短的跳跃距离

但是我们想要通过移走石头来使得选手这个最短跳跃距离达到最大

最终要求出这个最短跳跃距离。

对于最短跳跃距离x,和移走石头数c

当x增加,c也在增加

当x减小,c也在减少

-----------------------------------------------------------------

[1                                ans                                  L]

-----------------------------------------------------------------

当x <= ans时,移走的岩石小于等于 m

当x > ans时,移走的岩石c肯定大于 m (规定移走的岩石数)

left                        mid                       right

calc(mid)计算在最小跳跃距离为mid的时候,移走的石头数

calc(mid) <= m  在跳跃mid距离时,移走石头小于等于m  left = mid
calc(mid) >  m  在跳跃mid距离时,移走石头大于m  right = mid - 1

那么问题来了?如何计算当最小跳跃距离为mid的时候,移走的石头数呢?

这个地方我们可以通过双指针的方法来实现它:

一个指针i指向前一个石头,另外一个指针j向后查找,通过a[j] - a[i] < mid就让j++

当出现a[j] - a[i] >= mid就停止向后查找,因为根据题目可以知道向后会越来越大

然后通过i和j的下标计算出来中间移走的石头数量 j - i - 1

最后更新i的大小,i = j - 1 (因为在for循环里面还有一个i++) 让i更新指向j的位置

然后继续执行逻辑,最后得出这种情况的移走石头数量。

这样我们就可以去实现我们的代码了!

代码实现:

#include <iostream>
using namespace std;
const int N = 5e4 + 10;
typedef long long LL;
LL l, n, m;
LL a[N];
LL calc(LL x)
{//计算最短跳跃距离为x的时候,要移动的石头数LL ret = 0;// 记录石头数// 遍历石头 for (int i = 0; i < n; i++){int j = i + 1;while(j <= n && a[j] - a[i] < x) j++;ret += j - i - 1;i = j - 1;}return ret;
}
int main()
{cin >> l >> n >> m;for (int i = 1; i <= n; i++){cin >> a[i]; // 岩石距离起点距离 }a[n + 1] = l;//避免计算的错误n++; LL left = 1, right = l;while(left < right){LL mid = (left + right + 1) / 2;if (calc(mid) <= m) left = mid;else right = mid - 1;}cout << left << endl;return 0; 
}

结语

很高兴大家能够看到这里,希望前面内容的讲解能够给大家带来收获,弄懂二分答案的原理和使用场景,对于最后这道题可能比较难以理解,但是大家可以仔细思考思考。

如果这篇文章对您有所收获的话,请多多点赞 + 收藏 + 关注!

http://www.dtcms.com/a/404584.html

相关文章:

  • 深圳市建网站公制作网页的软件有哪些
  • 营销类网站有哪些设计主题和设计理念
  • 长沙做网站最好的公司c2c跨境电商平台有哪些?
  • 南京网站建站公司WordPress仿wp大学模板
  • 毕设代做的网站郑州建设银行网站房贷网点在哪
  • 音频网站模板网站查询ip解析
  • 桂林有帮做公司网站吗十堰市公司网站建设
  • html源码网站建设中wordpress 时间调用
  • 做网站前端有前途么?争对银行排队做一网站
  • 免费推广网站注册入口wordpress ios api
  • 江阴做网站的成都哪些公司做网站好
  • 企业名称查询网站企业网站模板下载软件
  • 智能网站建设公司排名给一个学校网站做宣传海报
  • 彭山网站建设家具网站素材
  • html论坛网站模板下载丽水做网站公司
  • ueeshop外贸建站公司网站功能简介
  • 上海建设公司网站wordpress企业站模板下载
  • 网站秒收录工具沧州网站设计师招聘
  • 建网站大公司企业网址一般怎么设置
  • 已经有域名 如何建网站社保网站哪里做转入
  • 关于自行建设门户网站的请示长春做网站大公司
  • 凡科删除建设的网站开发流程有哪些阶段
  • 高校文明建设网站seo伪原创工具
  • 美丽寮步网站建设wordpress博客数据放在哪里的
  • 大型网站建设兴田德润实惠公司域名备案
  • 厦门手机网站制作做内部网站费用
  • 机械厂网站建设方案wordpress打开越来越慢
  • 天河网站建设方案做淘宝客没网站吗
  • 为什么做旅游网站用国外网站 图片做自媒体
  • 网站设计英文网架加工费多少钱一吨