算法·二分

二分枚舉

適用條件:

  • 答案有明顯上下界
  • 答案具有單調性:a滿足,若b>=a可以知b必定滿足。
  • 本質上是枚舉的對數優化

思維技巧

  • 解決問題->>驗證答案,明顯前者比后者更加困難
  • 若題目有最大值最小,最小值最大這種經典條件,隱含著答案有界

模板

  • 左邊界和右邊界的界定
  • 判定函數
  • 二分模板
bool isValid(){//驗證答案
}
int l==a,r=b;
while(l<=r){int mid=(l+r)/2if(isValid(mid)){ans=mid;l=mid+1;}else{r=mid-1;}
}

以下均為題解

小鳥的設備

題目背景

小鳥有 n n n 個可同時使用的設備。

題目描述

i i i 個設備每秒消耗 a i a_i ai? 個單位能量。能量的使用是連續的,也就是說能量不是某時刻突然消耗的,而是勻速消耗。也就是說,對于任意實數,在 k k k 秒內消耗的能量均為 k × a i k\times a_i k×ai? 單位。在開始的時候第 i i i 個設備里存儲著 b i b_i bi? 個單位能量。

同時小鳥又有一個可以給任意一個設備充電的充電寶,每秒可以給接通的設備充能 p p p 個單位,充能也是連續的,不再贅述。你可以在任意時間給任意一個設備充能,從一個設備切換到另一個設備的時間忽略不計。

小鳥想把這些設備一起使用,直到其中有設備能量降為 0 0 0。所以小鳥想知道,在充電器的作用下,她最多能將這些設備一起使用多久。

輸入格式

第一行給出兩個整數 n , p n,p n,p

接下來 n n n 行,每行表示一個設備,給出兩個整數,分別是這個設備的 a i a_i ai? b i b_i bi?

輸出格式

如果小鳥可以無限使用這些設備,輸出 ? 1 -1 ?1

否則輸出小鳥在其中一個設備能量降為 0 0 0 之前最多能使用多久。

設你的答案為 a a a,標準答案為 b b b,只有當 a , b a,b a,b 滿足
∣ a ? b ∣ max ? ( 1 , b ) ≤ 1 0 ? 4 \dfrac{|a-b|}{\max(1,b)} \leq 10^{-4} max(1,b)a?b?10?4 的時候,你能得到本測試點的滿分。

解題思路

  • 注意題目描述:能量的使用是連續的,意味著可以從整體來看問題,如果充電量大于總耗電量,則一定可以無限使用,反之則不能。
  • 直接表達問題非常困難,但是從枚舉的角度驗證答案其實不難
  • 注意精度
#include<bits/stdc++.h>
using namespace std;
using ll = long long;
int n;
double p,ans=0;
vector<double>e(100009, 0); //當前電力
vector<double>ct(100009, 0);//消耗bool isValid(double s,vector<double>e) {for (int i = 1; i <= n; i++) {e[i] -= ct[i] * s;}double sum = p * s;for (int i = 1; i <= n; i++) {if (e[i] < 0) {sum += e[i];}if (sum < 0) {return false;}}return true;
}
void solve() {cin >> n >> p;double sume = 0;//總電力double cost = 0;for (int i = 1; i <= n; i++) {cin >> ct[i] >> e[i];sume += e[i];cost += ct[i];}if (cost <= p) {cout << -1;return;}double time = sume / (cost - p);//最大時間//cout << "sume==" << sume << " cost==" << cost <<" time==" <<time<< endl;double l = 0, r = time;while (l <= r) {double mid = (l+r)/2;if (isValid(mid, e)) {ans = mid;l = mid + 1e-5;}else {r = mid - 1e-5;}}printf("%f", ans);}
int main() {std::ios::sync_with_stdio(false);std::cin.tie(0); std::cout.tie(0);solve();return 0;
}

[COCI 2011/2012 #5] EKO / 砍樹

題目描述

伐木工人 Mirko 需要砍 M M M 米長的木材。對 Mirko 來說這是很簡單的工作,因為他有一個漂亮的新伐木機,可以如野火一般砍伐森林。不過,Mirko 只被允許砍伐一排樹。

Mirko 的伐木機工作流程如下:Mirko 設置一個高度參數 H H H(米),伐木機升起一個巨大的鋸片到高度 H H H,并鋸掉所有樹比 H H H 高的部分(當然,樹木不高于 H H H 米的部分保持不變)。Mirko 就得到樹木被鋸下的部分。例如,如果一排樹的高度分別為 20 , 15 , 10 20,15,10 20,15,10 17 17 17,Mirko 把鋸片升到 15 15 15 米的高度,切割后樹木剩下的高度將是 15 , 15 , 10 15,15,10 15,15,10 15 15 15,而 Mirko 將從第 1 1 1 棵樹得到 5 5 5 米,從第 4 4 4 棵樹得到 2 2 2 米,共得到 7 7 7 米木材。

Mirko 非常關注生態保護,所以他不會砍掉過多的木材。這也是他盡可能高地設定伐木機鋸片的原因。請幫助 Mirko 找到伐木機鋸片的最大的整數高度 H H H,使得他能得到的木材至少為 M M M 米。換句話說,如果再升高 1 1 1 米,他將得不到 M M M 米木材。

輸入格式

1 1 1 2 2 2 個整數 N N N M M M N N N 表示樹木的數量, M M M 表示需要的木材總長度。

2 2 2 N N N 個整數表示每棵樹的高度。

輸出格式

1 1 1 個整數,表示鋸片的最高高度。

解題思路

  • 正常的二分
  • 枚舉+最大
#include<bits/stdc++.h>
using namespace std;
using ll = long long;
int n,ans=0;
ll m; vector<int>v(1000009, 0);
bool isValid(int mid) {ll sum = 0;for (int i = 1; i <= n;i++) {if (mid > v[i]) {continue;}sum += (ll)(v[i] - mid);}if (sum >= m)return true;return false;
}
void solve() {cin >> n >> m;int maxlen = 0;for (int i = 1; i <= n; i++) {cin >> v[i];maxlen = max(v[i], maxlen);}int l = 0, r = maxlen;while (l <= r) {int mid = (l + r) / 2;/*cout << mid << endl;*/if (isValid(mid)) {ans = mid;l=mid+1;}else {r= mid - 1;}}cout << ans;
}int main() {std::ios::sync_with_stdio(false);std::cin.tie(0); std::cout.tie(0);solve();return 0;
}

數列分段 Section II

題目描述

對于給定的一個長度為 N N N 的正整數數列 A 1 ~ N A_{1\sim N} A1N?,現要將其分成 M M M M ≤ N M\leq N MN)段,并要求每段連續,且每段和的最大值最小。

關于最大值最小:

例如一數列 4 2 4 5 1 4\ 2\ 4\ 5\ 1 4?2?4?5?1 要分成 3 3 3 段。

將其如下分段:

[ 4 2 ] [ 4 5 ] [ 1 ] [4\ 2][4\ 5][1] [4?2][4?5][1]

第一段和為 6 6 6,第 2 2 2 段和為 9 9 9,第 3 3 3 段和為 1 1 1,和最大值為 9 9 9

將其如下分段:

[ 4 ] [ 2 4 ] [ 5 1 ] [4][2\ 4][5\ 1] [4][2?4][5?1]

第一段和為 4 4 4,第 2 2 2 段和為 6 6 6,第 3 3 3 段和為 6 6 6,和最大值為 6 6 6

并且無論如何分段,最大值不會小于 6 6 6

所以可以得到要將數列 4 2 4 5 1 4\ 2\ 4\ 5\ 1 4?2?4?5?1 要分成 3 3 3 段,每段和的最大值最小為 6 6 6

輸入格式

1 1 1 行包含兩個正整數 N , M N,M N,M

2 2 2 行包含 N N N 個空格隔開的非負整數 A i A_i Ai?,含義如題目所述。

輸出格式

一個正整數,即每段和最大值最小為多少。

解題思路

  • 判定函數:我感覺我的判定函數沒起到作用,因為當區間長度為1時,如果和sum>枚舉值時,這個枚舉值一定是無效的。
    但是如果不加入l=maxv對二分左邊界作限制,又過不了…
  • 應該對二分邊界作詳細界定,不能忽略的左邊界!!!
#include<bits/stdc++.h>
using namespace std;
using ll = long long;
int n, m,ans=0;
vector<int>v(100009, 0);
bool isValid(ll t,int m) {//t目標值,m是段數ll sum = 0;int i = 1;for (int j = 1; j <= n; j++) {sum += (ll)v[j];if (sum > t) {if (i < j) {sum = (ll)v[j];i = j;m--;}else {return false;}}}if (m < 1) {return false;}return true;
}
void solve() {cin >> n >> m;ll maxv = 0,sum=0;for (int i = 1; i <= n; i++) {cin >> v[i];maxv = max(maxv, (ll)v[i]);sum += (ll)v[i];}/*cout << "maxv==" << maxv <<" sum=="<<sum<< endl;*/ll l = maxv, r = sum,mid=0;while (l <= r) {mid = (l + r) / 2;if (isValid(mid, m)) {ans = mid;r = mid - 1;}else {l = mid + 1;}}cout << ans;
}
signed main() {std::ios::sync_with_stdio(false);std::cin.tie(0); std::cout.tie(0);solve();return 0;
}

煩惱的高考志愿

題目背景

計算機競賽小組的神牛 V 神終于結束了高考,然而作為班長的他還不能閑下來,班主任老 t 給了他一個艱巨的任務:幫同學找出最合理的大學填報方案。可是 v 神太忙了,身后還有一群小姑娘等著和他約會,于是他想到了同為計算機競賽小組的你,請你幫他完成這個艱巨的任務。

題目描述

現有 m m m 所學校,每所學校預計分數線是 a i a_i ai?。有 n n n 位學生,估分分別為 b i b_i bi?

根據 n n n 位學生的估分情況,分別給每位學生推薦一所學校,要求學校的預計分數線和學生的估分相差最小(可高可低,畢竟是估分嘛),這個最小值為不滿意度。求所有學生不滿意度和的最小值。

輸入格式

第一行讀入兩個整數 m , n m,n m,n m m m 表示學校數, n n n 表示學生數。

第二行共有 m m m 個數,表示 m m m 個學校的預計錄取分數。第三行有 n n n 個數,表示 n n n 個學生的估分成績。

輸出格式

輸出一行,為最小的不滿度之和。

樣例 #1

樣例輸入 #1

4 3
513 598 567 689
500 600 550

樣例輸出 #1

32

思路

  • 二分枚舉答案
  • 優化O(n*n)至O(nlogn)
  • 注意l=0,因為我排序了!!!下標從0開始了!!!!!
#include<bits/stdc++.h>
using namespace std;
using ll = long long;
int m, n;
vector<ll>student(100009, 0);
vector<ll>school(100009, INT_MAX);
ll search(int target) {ll l = 0, r = m,mid=0;ll minval = INT_MAX;while (l <= r) {mid = (l + r) / 2;      if (school[mid] < target) {minval = min(minval, abs(school[mid] - target));l = mid + 1;}else if (school[mid] == target) {return 0;}else {minval = min(minval, abs(school[mid] - target));r = mid - 1;}}return minval;
}
void solve() {cin >> m >> n;for (int i = 1; i <= m; i++) {cin >> school[i];}for (int i = 1; i <= n; i++) {cin >> student[i];}sort(school.begin(), school.end());//排序后下標改變了!!!ll sum = 0;for (int i = 1; i <= n; i++) {sum += search(student[i]);}cout << sum;
}
signed main() {std::ios::sync_with_stdio(false);std::cin.tie(0); std::cout.tie(0);solve();return 0;
}

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/41970.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/41970.shtml
英文地址,請注明出處:http://en.pswp.cn/web/41970.shtml

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

相關文章

Docker-11☆ Docker Compose部署RuoYi-Cloud

一、環境準備 1.安裝Docker 附:Docker-02-01☆ Docker在線下載安裝與配置(linux) 2.安裝Docker Compose 附:Docker-10☆ Docker Compose 二、源碼下載 若依官網:RuoYi 若依官方網站 鼠標放到"源碼地址"上,點擊"RuoYi-Cloud 微服務版"。 跳轉至G…

深入理解計算機系統 CSAPP 家庭作業8.22

書本知識夠你寫出答案,但是如果你想驗證你寫的答案,就要一些額外的東西.這本書很多題目都是如此 /** mysystem.c*/ #include <stdio.h> #include "csapp.h"int mysystem(char* command) {pid_t pid;int status;if ((pid Fork()) 0) {/*這里是關鍵用子程序去…

新加坡工作和生活指北:工作篇

文章首發于公眾號&#xff1a;Keegan小鋼 一年多以前&#xff08;2022 年 8 月初&#xff09;&#xff0c;那時我過來新加坡才 4 個多月&#xff0c;就寫了篇文章分享了當時在新加坡的生活和工作體驗。文章得到的反響不錯&#xff0c;但也反饋出了一些新的問題&#xff0c;比如…

預訓練對齊:數學理論到工程實踐的橋梁

在人工智能和機器學習領域&#xff0c;預訓練模型的對齊是一個至關重要的概念。本篇博客源自聽了一場黃民烈老師關于大模型對齊的分享&#xff0c;整理內容如下&#xff0c;供大家參考。 數學理論中的預訓練對齊 數學理論上&#xff0c;預訓練對齊是什么&#xff1f; 序列…

Java-關鍵字(static,final)

1.1 static關鍵字 static關鍵字 : 靜態的意思 , 可以修飾變量 , 也可以修飾方法 , 被static修飾的成員 , 我們叫做靜態成員 static特點 : 靜態成員被所類的所有對象共享 隨著類的加載而加載 , 優先于對象存在 可以通過對象調用 , 也可以通過類名調用 , 建議使用類名 1. 靜…

Keepalived+HAProxy 集群及虛IP切換實踐

1、軟件介紹 ①Keepalived keepalive是一個用c語言編寫的路由軟件&#xff0c;這個項目的主要目標是為Linux系統和基于Linux的基礎設施提供簡單而健壯的負載平衡和高可用性設施。負載均衡框架依賴于眾所周知且廣泛使用的Linux Virtual Server (IPVS)內核模塊提供第4層負載均衡…

srs直播內網拉流帶寬飆升問題記錄

問題背景 srs部署在云服務器上&#xff0c;32核cpu&#xff0c;64G內存&#xff0c;帶寬300M. 客戶端從srs拉流&#xff0c;發現外網客戶端拉流&#xff0c;cpu和帶寬都正常。然而內網客戶端拉流&#xff0c;拉流人數超過5人以上&#xff0c;帶寬就會迅速飆升。 排查 用srs…

數學建模論文寫作文檔word

目錄 1. 摘要寫法1.1 確定題目與方法1.2 編寫開頭段落1.3 填寫問題一1.4 重復步驟3填寫其他問題1.5 編寫結尾段落1.6 編寫關鍵詞 2. 問題重述2.1 問題背景2.2 問題提出 3. 問題分析4. 問題X模型的建立與求解5. 模型的分析5.1 靈敏度分析5.2 誤差分析&#xff08;主要用于預測類…

Milvus lite start 及存儲策略

背景 今天開始寫下Milvus&#xff0c;為了方便&#xff0c;我直接使用的是 milvus-lite 版本&#xff0c;default 情況下&#xff0c;你可能不知道他到底將 db 存儲到什么位置了。啟動 default-server&#xff0c;看下Milvus 的start及存儲邏輯 主邏輯 def start(self):sel…

adb參數詳解

文章目錄 1. -d2. -e3. -s4. -t5. -H6. -P7. -L8. --one-device9. --exit-on-write-error10. connect / disconnect11. pair12. forward13. forward --list14. reverse15. mdns check16. mdns services17. push18. pull19. sync20.shell21. install22. uninstall23. bugreport2…

最小二乘支持向量機(Least Squares Support Vector Machine,LSSVM)及其Python和MATLAB實現

LSSVM&#xff08;Least Squares Support Vector Machine&#xff09;又稱最小二乘支持向量機&#xff0c;是支持向量機&#xff08;SVM&#xff09;的一種變體&#xff0c;它通過將SVM的優化問題轉化為帶約束的二次規劃問題&#xff0c;利用最小二乘法進行優化求解&#xff0c…

redis集群部署 (通過redis工具快速部署,手動部署)

目錄 一、快速部署集群 1、 進入集群目錄&#xff0c;創建集群 2、 查看正常啟動 二、部署集群 1、分配集群節點 2、驗證集群可用性 3、停止redis進程 三、手動部署集群 1、配置redis.conf配置文件 2、啟動redis集群 3、手動創建redis集群 4、驗證 四、集群…

mysql異常數據損壞處理,報錯:Operating system error number 2 in a file operation

一、問題描述 某次一線反應&#xff0c;某主庫表全部丟失&#xff0c;查看為空&#xff0c;登陸主機查看mysqld.log后報錯&#xff1a;Operating system error number 2 in a file operation數據目錄OS重裝后修改過&#xff0c;但只是指向方式不同&#xff0c;目錄還是同一目錄…

【綠色版】Mysql下載、安裝、配置與使用(保姆級教程)

大家都知道&#xff0c;Mysql安裝版的卸載過程非常繁瑣&#xff0c;而且卸載不干凈會出現許多問題&#xff0c;很容易讓大家陷入重裝系統的窘境。基于此&#xff0c;博主今天給大家分享綠色版Mysql的安裝、配置與使用。 目錄 一、Mysql安裝、配置與使用 1、下載解壓 2、創建…

vue對axios進行請求響應封裝

一、原因 像是在一些業務邏輯上&#xff0c;比如需要在請求之前展示loading效果&#xff0c;或者在登錄的時候判斷身份信息&#xff08;token&#xff09;等信息有沒有過期&#xff0c;再者根據服務器響應回來的code碼進行相應的提示信息。等等在請求之前&#xff0c;之后做的一…

ABAP注釋快捷鍵修改(留著備用)

ABAP注釋快捷鍵修改(留著備用) 在使用ABAP編輯器的時候&#xff0c;原有的添加代碼注釋和取消代碼注釋的快捷鍵未生效&#xff0c;這時我們可以考慮對注釋快捷鍵進行修改 在事務碼SE38(ABAP編輯器)屏幕右下角&#xff0c;點擊【Options選項】圖標 在【鍵盤】|【命令】輸入欄中…

DWM 相關實現代碼 [自用]

1. DWM 縮略圖和模糊隱藏實現半透明 #include <windows.h> #include <dwmapi.h> #include <string> #pragma comment(lib, "dwmapi.lib")// 檢查 UWP 窗口是否可見 bool IsUWPWindowVisible(HWND hwnd) {DWORD cloaked 0;DwmGetWindowAttribute(…

【c語言】玩轉文件操作

&#x1f31f;&#x1f31f;作者主頁&#xff1a;ephemerals__ &#x1f31f;&#x1f31f;所屬專欄&#xff1a;C語言 目錄 引言 一、文件的打開和關閉 1.流 2.標準流 3.文本文件和二進制文件 4.控制文件打開與關閉的函數 二、文件的順序讀寫 三、文件的隨機讀寫 1…

深入理解OAuth 2.0:原理、流程與實踐

一、什么是OAuth 2.0 1. 什么是OAuth 2.0 OAuth 2.0 是一套關于授權的行業標準協議。 OAuth 2.0 允許用戶授權第三方應用訪問他們在另一個服務提供方上的數據&#xff0c;而無需分享他們的憑據&#xff08;如用戶名、密碼&#xff09;。 2. OAuth 2.0 應用場景 OAuth 2.0的…

非參數檢測6——優缺點

優點&#xff1a; 參量檢測的特點在于以似然比處理器為基礎&#xff0c;并建立在假定干擾或噪聲的統計特性已知的基礎上。但實際上&#xff0c;干擾環境往往十分復雜&#xff0c;包括自然和人為因素&#xff0c;且常常隨時改變。這使我們很難確定噪聲的統計特性。因此人們提出…