zoukankan      html  css  js  c++  java
  • 数学 砍树

    这里写图片描述
    Σ (向上取整(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)
    易知两个函数都是单调不上升的。具体来说都是分段的,那么对于g(d)的同一段上,段尾的d值一定优于段首值(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;
    }
  • 相关阅读:
    U-Boot新手入门
    安装交叉编译工具
    Makefile 工程管理
    gcc基本用法
    poj 3264 Balanced Lineup
    hdoj 1166 敌兵布阵
    poj 1363 Rails
    poj 1028 Web Navigation
    zoj 3621 Factorial Problem in Base K
    poj1861最小生成树
  • 原文地址:https://www.cnblogs.com/QTY2001/p/7632678.html
Copyright © 2011-2022 走看看