二分+最大化最小值 River Hopscotch POJ - 3258
題意:
起始有兩個石頭,位置是000和nnn,在這中間有n個石頭,問如何拿走m塊石頭后,使得他們之間的最小間隔的最大值。
題目:
Every year the cows hold an event featuring a peculiar version of hopscotch that involves carefully jumping from rock to rock in a river. The excitement takes place on a long, straight river with a rock at the start and another rock at the end, L units away from the start (1 ≤ L ≤ 1,000,000,000). Along the river between the starting and ending rocks, N (0 ≤ N ≤ 50,000) more rocks appear, each at an integral distance Di from the start (0 < Di < L).
To play the game, each cow in turn starts at the starting rock and tries to reach the finish at the ending rock, jumping only from rock to rock. Of course, less agile cows never make it to the final rock, ending up instead in the river.
Farmer John is proud of his cows and watches this event each year. But as time goes by, he tires of watching the timid cows of the other farmers limp across the short distances between rocks placed too closely together. He plans to remove several rocks in order to increase the shortest distance a cow will have to jump to reach the end. He knows he cannot remove the starting and ending rocks, but he calculates that he has enough resources to remove up to M rocks (0 ≤ M ≤ N).
FJ wants to know exactly how much he can increase the shortest distance before he starts removing the rocks. Help Farmer John determine the greatest possible shortest distance a cow has to jump after removing the optimal set of M rocks.
Input
Line 1: Three space-separated integers: L, N, and M
Lines 2…N+1: Each line contains a single integer indicating how far some rock is away from the starting rock. No two rocks share the same position.
Output
Line 1: A single integer that is the maximum of the shortest distance a cow has to jump after removing M rocks
Sample Input
25 5 2
2
14
11
21
17
Sample Output
4
Hint
Before removing any rocks, the shortest jump was a jump of 2 from 0 (the start) to 2. After removing the rocks at 2 and 14, the shortest required jump is a jump of 4 (from 17 to 21 or from 21 to 25).
分析:
由于是求最小間隔的最大值,(起初我理解成求出最大間隔,那么直接連續拿,遍歷一遍就好,那肯定是錯的),那么如何處理每次拿走石頭都有可能改變之間間隔的最小值呢?
1.首先考慮到,只要拿走石頭都會使石頭之間的間隔變大,那么我們只需要枚舉最小的間隔,看是否滿足拿走k個石頭后,仍舊是最小間隔。
2.那么如何求的最大的最小間隔呢,我們用二分進行枚舉最小間隔即可
3.對石頭位置進行排序,為之后的遍歷尋找去掉一個石頭后計算之間的間隔做準備。
4.dfs(x)=xdfs(x)=xdfs(x)=x是所有石頭間的最小間隔,即任意兩個石頭之間的間隔都不能小于xxx,我們可以拿走k塊石頭,那就判斷,當拿走k塊石頭后,仍是最小間隔即可。當存在拿走大于等于k個石頭后,仍舊是最小間隔時,說明此時最小間隔偏大(我們最終需要的是正好拿走k個石頭,使得該枚舉的最小間隔,是石頭間的最小間隔)
AC代碼:
#include<string.h> #include<stdio.h> #include<algorithm> #include<iostream> using namespace std; const int M=5e4+10; int n,m,k; int f[M]; bool dfs(int x){///假設x是所有石頭間的最大最小間隔,則此時需要判斷拿走k個石頭后,是否仍是最小間隔。int num=0;for(int i=1;i<m-k;i++){///一共m-2-k次循環,哪怕不滿足while循環pre=m-kint pre=num+1;while(pre<m&&f[pre]-f[num]<x){///當存在石頭間隔小于最小間隔,拿走這個石頭,使間隔變大pre++;}if(pre==m){///若假設成立,存在拿走>=k塊石頭讓石頭間隔小于最小間隔;return false;}num=pre;}return true; } int main(){cin>>n>>m>>k;f[0]=0;for(int i=1;i<=m;i++){cin>>f[i];}f[m+1]=n;m=m+2;sort(f,f+m);int r=0,l=n+1;//上界要稍大一些,否則mid永遠取不到值nwhile(l-r>1){int mid=(r+l)>>1;if(dfs(mid))//說明此時枚舉的間隔較小r=mid;else l=mid;//是否可能使得所有石頭之間的距離不小于d}cout<<r<<endl;return 0; } 創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎總結
以上是生活随笔為你收集整理的二分+最大化最小值 River Hopscotch POJ - 3258的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 后悔贪心+P2949 [USACO09O
- 下一篇: 可降解支架什么意思