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

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值