p1888

.

一开始确实想到了dfs,但是感觉挺难搞。

然后想象自己已经知道了答案,那么需要的人数就可以用复杂度为m算出。那么二分答案可不可以呢?

先找到栏杆长度最大的那个值,二分它。判断的时候可以贪心的算,如果当前是x,就让所有人能做这么大就做这么大。如果不够了再少做一些。也就是sum+=o[i]/x,如果除不尽就再sum++。

二分答案是log210^9,每次判断是m,可以跑完。

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<string>
#include<algorithm>
#include<vector>
#include<map>
#include<stack>
#include<queue>
#include<deque>
#include<set>
using namespace std;
int i;
int n,m,sum,t;
int o[300010];
bool check(int x)
{
    sum=0;
    for(i=1;i<=m;i++)
    {
        t=o[i]/x;
        sum+=t;
        if(t*x<o[i])
            sum++;
    }
    if(sum>n)return 0;
    else     return 1;
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(NULL);
cout.tie(NULL);
//freopen("123.in","r",stdin);
//freopen("123.out","w",stdout);    
    cin>>n>>m;
    for(i=1;i<=m;i++)
        cin>>o[i];
    sort(o+1,o+1+m);//图省事写了个sort
    int left=1,right=o[m],mid;
    while(left+1<right)
    {
        mid=(left+right)/2;
        if(check(mid)) right=mid;
        else           left=mid;
    }
    if(check(left))cout<<left;
    else           cout<<right;
}

 

posted @ 2018-08-14 17:25  zzuqy  阅读(197)  评论(0编辑  收藏  举报