1. 程式人生 > >Educational Codeforces Round 18 E. Colored Balls 分塊思想+思維

Educational Codeforces Round 18 E. Colored Balls 分塊思想+思維

/***
連結:https://codeforces.com/contest/792/problem/E
題意:給定長度為n的序列a[i],拆分每一個a[i];
使得拆分的每一個a[i]得到的所有任意兩個子序列的大小之差不超過1;
求:最小的能拆分的滿足條件的子序列的個數
分析;列舉貪心即可 分塊思想 每次設定塊值的上限(size) 
儘可能的越大越好,一旦滿足條件 直接退出即可;
********tricks********
細節.... 
不能夠整除的情況,應該取出每個完整塊的一一份+非完整塊的和與x-1進行比較
每個塊的權值浮動為[x-1,x];
因此轉換一下就是a[i]/x+a[i]%x>=x-1 即可;
*/


#include<bits/stdc++.h>
#define ll long long
using namespace std;

const int maxn=1e3+7;
int a[maxn],n;

ll check(int x){
    ll sum=0;
    for(int i=1;i<=n;i++){
        if(a[i]%x==0) sum+=a[i]/x;
        else if(a[i]/x+a[i]%x>=x-1) sum+=a[i]/x+1;
        else return 0;
    }
    return sum;
}

int main (){
    scanf("%d",&n);
    for(int i=1;i<=n;i++) scanf("%d",&a[i]);
    sort(a+1,a+1+n);
    ll ans;
    for(int i=1;i<=a[1];i++){
        ans=check(a[1]/i+1); if(ans) break;//分塊思想 每次選擇最大的一端
        ans=check(a[1]/i);   if(ans) break;
        ans=check(a[1]/i-1); if(ans) break;
    }
    printf("%lld\n",ans);
    return 0;
}