日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

洛谷 P1824 进击的奶牛 【二分答案】(求最大的最小值)

發布時間:2024/7/19 编程问答 39 豆豆
生活随笔 收集整理的這篇文章主要介紹了 洛谷 P1824 进击的奶牛 【二分答案】(求最大的最小值) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

題目鏈接:https://www.luogu.org/problemnew/show/P1824

題目描述

Farmer John建造了一個有N(2<=N<=100,000)個隔間的牛棚,這些隔間分布在一條直線上,坐標是x1,...,xN (0<=xi<=1,000,000,000)。

他的C(2<=C<=N)頭牛不滿于隔間的位置分布,它們為牛棚里其他的牛的存在而憤怒。為了防止牛之間的互相打斗,Farmer John想把這些牛安置在指定的隔間,所有牛中相鄰兩頭的最近距離越大越好。那么,這個最大的最近距離是多少呢?

輸入格式:

第1行:兩個用空格隔開的數字N和C。

第2~N+1行:每行一個整數,表示每個隔間的坐標。

輸出格式:

輸出只有一行,即相鄰兩頭牛最大的最近距離。

輸入樣例#1: 5 3 1 2 8 4 9 輸出樣例#1:?
3

解題思路:
像這種求最大最小值,最小最大值得問題都是典型的二分答案題,二分答案的主要難點在于juge()函數,此題下面給出了兩個不同思路的juge函數。

要注意的是如何根據所枚舉的答案來將隔間分隔,因為求的是最大的最近距離,這個距離要是每一次分隔距離中最短的。接下來分析,假設隔間的坐標沒有規定在哪的話,那么什么時候最近距離最大呢?毫無疑問,是當所有的距離
相同的時候,最近距離最大。但是此題每個隔間的坐標有規定,使得不一定能使每一段的距離都能夠相等,所以,此時求最近距離的最優思路就是:

? ?每一段區間距離都應該大于或等于m(但要盡可能的接近最近距離),這樣才能使最近距離最大
?所以一旦所枚舉的隔間距離恰好大于最近距離的時候,就在該隔間放牛,毫無疑問,這樣得到的最近距離才會盡可能的大

?

第一種juge()函數

bool juge(int m)//判斷距離m是否可以 {int s = 0, last = 1;//記錄上一個 for (int i = 2; i <= n; i++)//依次枚舉每個牛欄 {if (a[i] - a[last]<m)s++;//若此距離不滿足當前答案,那么需要的牛欄數+1,即把當前牛放到下一個牛欄 else last = i;//否則就更新上一次的牛欄位置 ,即上一頭牛放的位置 if (s>n - c) return false;//若需要牛欄數大于最大牛欄數,此答案不可行 }return true; }
第二種juge()函數
bool juge(int m) {int ans = 1, last = 1; //因為第一個牛一定要占據第一個隔間(這樣能使本題的答案最優),所以ans初始化為1for (int i = 2; i <=n; i++){if (a[i] - a[last] >= m){ans++; //如果比最近距離要大的話,那么該隔間就放牛 last = i; }}if (ans >= c)return true; return false; }

?

本題代碼

#include <bits/stdc++.h> using namespace std; int a[100010]; int l, r; int n,c;/*bool juge(int m)//判斷距離m是否可以 {int s = 0, last = 1;//記錄上一個 for (int i = 2; i <= n; i++)//依次枚舉每個牛欄 {if (a[i] - a[last]<m)s++;//若此距離不滿足當前答案,那么需要的牛欄數+1,即把當前牛放到下一個牛欄 else last = i;//否則就更新上一次的牛欄位置 ,即上一頭牛放的位置 if (s>n - c) return false;//若需要牛欄數大于最大牛欄數,此答案不可行 }return true; }*/bool juge(int m) {int ans = 1, last = 1; //因為第一個牛一定要占據第一個隔間(這樣能使本題的答案最優),所以ans初始化為1for (int i = 2; i <=n; i++){if (a[i] - a[last] >= m){ans++; //如果比最近距離要大的話,那么該隔間就放牛 last = i; }}if (ans >= c)return true; //如果所選取的隔間數量>=c,則說明枚舉的最近距離成立,但是不夠大,所以return true,繼續枚舉更大的距離return false; }int main() {cin >> n >> c;for (int i = 1; i <=n; i++)cin >> a[i];l = 1; r = a[n] - a[1]; //右邊界為n個隔間的總長度,最近距離一定小于等于這個數值sort(a + 1, a + 1 + n);while (l <= r){int mid = (l + r)/2;if (juge(mid))l = mid+1; //如果當前枚舉的最近距離符合,那么就讓l=mid,看更大的距離是否也符合(因為要求最大的最近距離)elser = mid-1;}cout << r<< endl; //由于最后l<=r的時候還會運行一次,會讓l-1(如果答案正確的話),所以應該輸出的是rreturn 0; }
2018-05-20

轉載于:https://www.cnblogs.com/00isok/p/9063340.html

總結

以上是生活随笔為你收集整理的洛谷 P1824 进击的奶牛 【二分答案】(求最大的最小值)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。