基礎算法之二分算法 --- 2

大家好,不同的時間,相同的地點,時隔多日我們又見面了。繼上次的二分算法后,我們這次要來學習的是二分答案了。這個部分相較于前面的二分算法難度有相當的提升,希望大家有所準備。雖然難度增加了,但是博主還是會將其講明白講清楚的

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.pswp.cn/news/922097.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/922097.shtml
英文地址,請注明出處:http://en.pswp.cn/news/922097.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

發揮nano banana的最大能力

1. 概述Nano Banana 簡介&#xff1a;Nano Banana 是 Google DeepMind 開發的 AI 圖像生成與編輯模型&#xff0c;集成在 Google Gemini 平臺中&#xff08;具體為 Gemini 2.5 Flash 版本&#xff09;。它以高效的圖像編輯能力聞名&#xff0c;尤其在角色一致性、光影理解和快速…

leetcode 面試題01.02判定是否互為字符重排

一、問題描述二、解題思路解法一&#xff1a;對s1和s2進行sort排序&#xff0c;返回s1是否等于s2&#xff1b;解法二&#xff1a;用哈希表分別來記錄s1和s2中字符出現的次數&#xff0c;統計完后&#xff0c;判斷兩個哈希表是否相等;三、代碼實現解法一&#xff1a;時間復雜度&…

Python Yolo8 物體識別

支持單張圖片/圖片目錄批量預標注 默認使用cuda GPU .env HTTP_PROXYhttp://192.168.2.109:10808 HTTPS_PROXYhttp://192.168.2.109:10808pyproject.toml [project] name "yolo-test" version "0.1.0" description "Add your description here&quo…

LeetCode100-234回文鏈表

本文基于各個大佬的文章上點關注下點贊&#xff0c;明天一定更燦爛&#xff01;前言Python基礎好像會了又好像沒會&#xff0c;所有我直接開始刷leetcode一邊抄樣例代碼一邊學習吧。本系列文章用來記錄學習中的思考&#xff0c;寫給自己看的&#xff0c;也歡迎大家在評論區指導…

BUG排查流程

引言簡述Bug排查的重要性分享個人或團隊在Bug排查中的常見挑戰引出日記形式記錄的價值日記格式設計時間戳&#xff1a;記錄問題發現和解決的時間節點問題描述&#xff1a;清晰定義Bug的現象和影響范圍環境信息&#xff1a;操作系統、版本號、依賴庫等關鍵配置復現步驟&#xff…

汽車功能安全 Functional Safety ISO 26262 測試之一

汽車電子電氣系統的日益復雜使得功能安全成為保障車輛可靠性和駕乘安全的關鍵。 本文將圍繞ISO 26262標準的核心內容展開&#xff0c;幫助大家理解如何通過系統化的方法控制風險&#xff0c;進行測試&#xff0c;確保產品安全。 01 什么是功能安全&#xff1f; 首先&#xff0c…

人形機器人賽道的隱形勝負手:低延遲視頻鏈路如何決定機器人未來

一、引言&#xff1a;爆發前夜的人形機器人賽道 2025 年&#xff0c;被業內稱為“人形機器人量產元年”。政策與資本的合力&#xff0c;讓這條原本還帶著科幻色彩的產業賽道&#xff0c;驟然進入現實加速期。國家層面&#xff0c;《“機器人”行動計劃》明確提出要推動人形機器…

從iPhone 17取消SIM卡槽,看企業如何告別“數據孤島”

9月10日&#xff0c;蘋果公司如期召開秋季新品發布會&#xff0c;正式推出iPhone 17系列。除了性能和拍照的常規升級&#xff0c;一個看似不起眼但意義深遠的改變引起了廣泛關注——iPhone 17 Pro系列全面取消了實體SIM卡槽&#xff0c;只保留了eSIM功能。這一舉動不僅僅是技術…

【JavaWeb01】Web介紹

文章目錄1.導學2.Web開發介紹2.1 Web網站的工作流程2.2 前后端分離開發1.導學 2.Web開發介紹 2.1 Web網站的工作流程 瀏覽器根據請求的域名請求對應的前端服務器&#xff0c;前端服務器接收到請求之后&#xff0c;把對應的前端代碼返回給服務器。瀏覽器中有解析前端代碼的解析引…

鏈路預測算法MATLAB實現

鏈路預測算法MATLAB實現 鏈路預測是復雜網絡分析中的重要任務&#xff0c;旨在預測網絡中尚未連接的兩個節點之間未來產生連接的可能性。 程序概述 MATLAB程序實現了以下鏈路預測算法&#xff1a; 基于局部信息的相似性指標&#xff08;Common Neighbors, Jaccard, Adamic-Adar…

淘寶商品詳情 API 的安全強化與生態協同創新路徑

一、安全強化&#xff1a;從 “被動防御” 到 “主動免疫” 的體系升級動態身份認證與權限顆粒化構建 “生物特征 設備指紋 行為基線” 的三重認證機制&#xff1a;結合用戶操作習慣&#xff08;如點擊間隔、滑動軌跡&#xff09;生成動態令牌&#xff0c;對高權限接口&#…

快消26屆聯合利華校招AI測評及第二輪線上認知能力測評SHL筆試真題及評分要求

在求職的道路上&#xff0c;聯合利華作為一家全球知名企業&#xff0c;其招聘流程一直備受關注。尤其是其AI面試環節&#xff0c;更是讓許多求職者既期待又緊張。本文將詳細總結聯合利華AI面試的規律與應對策略&#xff0c;希望能為正在準備面試的你提供一些幫助。一、聯合利華…

使用Langchain生成本地rag知識庫并搭載大模型

準備設備&#xff1a; 手機aidlux2.0個人版 一、下載依賴pip install langchain langchain-community faiss-cpu pypdf二、安裝ollama并下載模型 curl -fsSL https://ollama.com/install.sh | sh #需要科學上網 ollama serve & #讓ollama服務在后臺運行安裝完畢可以查看oll…

L2-【英音】地道語音語調--語調

文章目錄語調英式語調四步法語調含義降調升調降升調升降語調如何正確表情達意1. 用降調的句型語調 英語里沒有任何一句話具有固定節奏模式 英式語調四步法 意群劃分重音核心語調&#xff08;重中之重&#xff09;語調的選擇 A French burglar broke-into-a flat while the o…

計算機視覺進階教學之圖像投影(透視)變換

目錄 簡介 一、了解圖像投影(透視)變換 一、定義與原理 二、應用場景 三、實現方法 二、案例分析 1. 輔助函數定義 1.1.cv_show 函數 1.2.order_points 函數 1.3.four_point_transform 函數 1.4.resize 函數 2. 主程序執行流程 2.1.圖像縮放處理 2.2.輪廓檢測 2.…

Java面試問題記錄(二)

三、系統設計與問題排查1、假設你要設計一個 “秒殺系統”&#xff0c;需要考慮高并發、高可用、防超賣等問題&#xff0c;你的整體技術方案是什么&#xff1f;從前端、接口層、服務層、存儲層分別說說核心設計點。秒殺系統設計設計核心&#xff1a;瞬時高并發&#xff0c;庫存…

k8s部署kafka三節點集群

本來認為部署kafka很簡單&#xff0c;沒想到也折騰了2-3天&#xff0c;這水平沒治了&#xff5e; kafka從3.4.0版本之后&#xff0c;可以不依賴zookeeper直接使用KRaft模式部署&#xff0c;也就是說部署kafka可以不安裝zookeeper直接部署。 在官網上沒有找到如何使用yaml文件…

在公用同一公網IP和端口的K8S環境中,不同域名實現不同訪問需求的解決方案

目錄 1. 訪問需求 2. 解決方案 3. 具體配置 3.1 允許互聯網訪問的域名&#xff08;a.lmzf.com&#xff09; 3.2 需IP白名單訪問的域名&#xff08;b.lmzf.com&#xff09; 3.3 關鍵參數說明 3.4 測試驗證 1. 訪問需求 在騰訊云TKE環境中&#xff0c;多個域名解析到同一…

FlinkCDC 達夢數據庫實時同步

一、Flink部署 1.1、JAVA環境 vi /etc/profile export JAVA_HOME/data/flinkcdc/jdk1.8.0_181 export CLASSPATH$JAVA_HOME/lib/tools.jar:$JAVA_HOME/lib/dt.jar export PATH$JAVA_HOME/bin:$PATHsource /etc/profilevi ~/.bash_profileexport FLINK_HOME/data/flinkcdc/fli…

Eip開源主站EIPScanner在Linux上的調試記錄(二 多生產者連接)

目錄 一、背景 二、可行性驗證 三、開發調試 一、背景 在一般場景下&#xff0c;只需一路IO連接&#xff0c;但稍微復雜的場景&#xff0c;就需要不同通訊周期的連接&#xff0c;這就需要有多組IO連接。 而大于一組的連接調試方法是一樣的&#xff0c;因此主要解決2組連接的…