ACM_二分(POJ1064)
阿新 • • 發佈:2018-12-15
1.二分法求解問題的這種思想其實十分的普遍。回憶一下我們在求一個方程的近似根的時候其實使用的就是二分的辦法,當然這種求近似根的方法是有一定侷限的,因為這樣無法求不變號的零點,也就說哪種曲線剛剛好與座標軸相切的零點我們通過普通的二分是無法求得的。但是,二分求近似根這種方法體現出來的二分思想其實是可以被用來解決很多的問題。
2.二分查詢。如果我們在一個有序的數組裡查詢不大於某個數最大的下標,其實我們就可以通過二分來做,具體的程式碼在這裡就不寫了,思想和求根一樣,不斷的二分查詢區間,直到找到為止。這樣其實我們把複雜度下降到logn。
3.繩子的切割問題這個問題的大概意思就是給你一些繩子,和一個整數K,讓你把這些繩子切割成K根長度相同的繩子並且使得這K根繩子儘可能的長。拿到這個問題,我們該如何分析呢?我們對最終的長度分析,設每一根根繩子的長度為x,那麼我們可以知道的是,在長度為x的時候我們可以切出來的就是
#include<iostream> #include<cstdio> #include<stdio.h> #include<math.h> #pragma warning(disable:4996) using namespace std; const int maxn = 1e4 + 10; int N, K; double len[maxn]; #define INF 2e5+10; bool OK(double c) { int num = 0; for (int i = 0; i < N; i++) { num += (int)(len[i] / c); } return num >= K; } void solve() { double l = 0; double r = INF; for (int i = 0; i < 100; i++) { double mid = (l + r) / 2; if (OK(mid))l = mid; else r = mid; } printf("%0.2f\n", floor(r * 100) / 100); } int main() { while (cin >> N >> K) { for (int i(0); i < N; i++) scanf("%lf", len + i); solve(); } return 0; }