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; }