洛谷 P1824 进击的奶牛 【二分答案】(求最大的最小值)
生活随笔
收集整理的這篇文章主要介紹了
洛谷 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 进击的奶牛 【二分答案】(求最大的最小值)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: adb push ,adb pull和a
- 下一篇: 关于线性代数的理解