1. 程式人生 > >洛谷【P1873】砍樹

洛谷【P1873】砍樹

思路 const 應該 com long check max log char

我對二分的理解:https://www.cnblogs.com/AKMer/p/9737477.html

題目傳送門:https://www.luogu.org/problemnew/show/P1873

我們可以二分高度\(high\)。顯然對於能砍出\(m\)米木材的\(high\),任何小於\(high\)的高度都不會更優(因為米爾科只需要\(m\)米木材並且他十分關註生態保護)。那麽\([1,high]\)這個區間就不是備選答案區間了,我們就應該到\([high,mx]\)裏去找盡可能高的\(high\),使得當伐木機鋸片在\(high\)米時可以砍下大於等於\(m\)的木材,而在\(high+1\)時必然小於\(m\)

時間復雜度:\(O(nloga)\)

空間復雜度:\(O(n)\)

代碼如下:

#include <cstdio>
#include <algorithm>
using namespace std;

const int maxn=1e6+5;

int a[maxn];
int n,mn,mx,m,ans;

int read() {
    int x=0,f=1;char ch=getchar();
    for(;ch<'0'||ch>'9';ch=getchar())if(ch=='-')f=-1;
    for(;ch>='0'&&ch<='9';ch=getchar())x=x*10+ch-'0';
    return x*f;
}

bool check(int high) {
    long long res=0;
    for(int i=1;i<=n;i++)
        if(a[i]>high)res+=a[i]-high;
    return res>=m;//計算high這個高度可以砍下多少木材並且判斷是否滿足要求
}

int main() {
    n=read(),m=read();mn=1,mx=-1e9;
    for(int i=1;i<=n;i++)
        a[i]=read(),mx=max(mx,a[i]);
    int l=mn,r=mx;
    while(l<=r) {
        int mid=(l+r)>>1;
        if(check(mid))ans=mid,l=mid+1;
        else r=mid-1;//根據上述思路二分
    }printf("%d\n",ans);
    return 0;
}

洛谷【P1873】砍樹