列舉演算法之最大值
阿新 • • 發佈:2018-12-11
題目描述
有一條河,河中間有一些石頭,已知石頭的數量和相鄰兩塊石頭之間的距離。現在可以移除一些石頭,問最多移除m塊石頭後(首尾兩塊石頭不可以移除),相鄰兩塊石頭之間的距離的最小值最大是多少。
輸入資料
第一行輸入兩個數字,n(2<=n<=1000)為石頭的個數,m(0<=m<=n-2)為可移除的石頭數目 隨後n-1個數字,表示順序和相鄰兩塊石頭的距離d(d<=1000)
輸出資料
輸出最小距離的最大值
樣例輸入
4 1
1 2 3
樣例輸出
3
解題:
列舉演算法,二分法。
求滿足條件fun()的最大值。可轉化為任意兩個求相鄰石頭間距離不小於d。
#include<cstdio> #include<algorithm> using namespace std; int a[50001]={0},l,n,m,i; bool fun(int m); int main() { scanf("%d%d",&n,&m); int left=0,right=l,mid,ans; for(i=1;i<=n;i++) scanf("%d",&a[i]); sort(a,a+(n+1)); while(right>=left) { mid=(left+right)/2;//mid表示最小的距離! if(fun(mid)) { left=mid+1; ans=mid; } else right=mid-1; } printf("%d\n",ans); } bool fun(int mid) { int start=0,x=0;//用start表示每次落腳點的座標,每落一次地更新一次start for(i=1;i<=n;i++) { if(a[i]-start<mid) x++;//x表示去掉的石頭數,如果mid大於要跳的距離,就跳過當前這個石頭,此時x++ ,並且不落地 else start=a[i];//此時落地! } if(l-start<mid)//判斷最後一跳跳的距離要是小於mid的話那是不可以的 return false; if(x>m)//要是x>m就說明最小距離mid太大啦 return false; return true; }