Educational Codeforces Round 18 E. Colored Balls 分块思想+思维

版权声明:布呗之路的守望者 https://blog.csdn.net/hypHuangYanPing/article/details/82829392
/***
链接: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;
}

猜你喜欢

转载自blog.csdn.net/hypHuangYanPing/article/details/82829392