生活随笔
收集整理的這篇文章主要介紹了
数学 砍树
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
Σ (向上取整(a[i]/d)*d-a[i])<=k
Σ(向上取整(a[i]/d))<=k+Σa[i](總稱為C)
Σ向上取整(a[i]/d)<=向下取整(C/d);
f(d)=Σ向上取整(a[i]/d),g(d)=向下取整(C/d)
易知兩個函數(shù)都是單調不上升的。具體來說都是分段的,那么對于g(d)的同一段上,段尾的d值一定優(yōu)于段首值(f(d)也單調下降)。
那么枚舉每一個段尾的d值,暴力求f(d),更新答案即可。
PS:設段首為i,段尾=C/(C/i);神奇。。
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<cmath>
#define ll long long
using namespace std;
int n;
ll k,a[
105],ans;
inline int read()
{
int sum=
0,f=
1;
char x=getchar();
while(x<
'0'||x>
'9'){
if(x==
'-')f=-
1;x=getchar();}
while(x>=
'0'&&x<=
'9'){sum=(sum<<
1)+(sum<<
3)+x-
'0';x=getchar();}
return sum*f;
}
int main()
{n=read();
scanf(
"%lld",&k);
for(
int i=
1;i<=n;i++)
scanf(
"%lld",&a[i]),k+=a[i];ll i=
1,j,t;
while(
1){t=k/i;
if(t==
0)
break;j=k/t;ll sum=
0;
for(
int l=
1;l<=n;l++){ll h=a[l]/j;
if(h*j<a[l])h++;sum+=h;
if(sum>t)
break;}
if(sum<=t)ans=j;i=j+
1;}
cout<<ans;
}
轉載于:https://www.cnblogs.com/QTY2001/p/7632678.html
總結
以上是生活随笔為你收集整理的数学 砍树的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。