1. 程式人生 > >木材加工(裸二分題)(附二分算法粗略介紹)

木材加工(裸二分題)(附二分算法粗略介紹)

iostream clu scanf 題意 int 一個數 二分 範圍 col

看到旁邊的學弟也在做二分,就手賤2分鐘打了一道奇(sha)特(bi)二分題。

原題傳送門

好吧,做這道題是為了給新手一個教程

首先我們聊聊二分。

二分利用的也是分治思想

不懂分治思想的可以看看我歸並做的那道火柴排隊。

傳送門

首先要了解一下二分的性質(也就是什麽題目要用二分來寫、)

我們假設一個題目,如果一個數a能夠滿足題意,並且U=[數值最小值/數值最大值(看題意)~a]中的數就一定能夠滿足題意。

那麽這道題目就能用來二分。。

或者說一道題目的解的解集為U,如0<i<a;題目的範圍是0<i<l;已知l>a;要我們求a的值

那麽這道題目就能用來二分。、

好吧,好想還是很復雜。

還是貼代碼比較穩妥。

簡單一句話來說,就是答案具有單調性的題目可以用來二分。。(單調性等我開始做單調隊列的時候再來填坑。。)

下面貼原題代碼。。主程序相當於模板啦233~

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int n,k,a[10001];
bool check(int x)
{
    int ans=0;
    for(int i=1;i<=n;i++)
    ans+=a[i]/x;
    
return ans>=k; } int main(){ int maxn=0; scanf("%d%d",&n,&k); for(int i=1;i<=n;i++) { scanf("%d",&a[i]); if(maxn<a[i])maxn=a[i]; } int l=1,r=maxn; int ans=0; while(l<=r) { int mid=(l+r)>>1; if(!check(mid))r=mid-1
; else ans=mid,l=mid+1; } printf("%d\n",ans); }

木材加工(裸二分題)(附二分算法粗略介紹)