当前位置: 代码迷 >> 综合 >> Colored Balls[CF-792E](分块)
  详细解决方案

Colored Balls[CF-792E](分块)

热度:92   发布时间:2023-11-19 10:13:12.0

文章目录

  • 题目
  • 思路
  • 代码
  • 思考

题目

nnn 种颜色的球,第 iii 种球有 aia_iai? 个,让你把球分成几个集合。
要求:

  • 一个集合里的球只能有一种颜色。
  • 每两个集合的球的数量相差不能 >1>1>1

让你求出这些球最少分几个集合。
1≤N≤500,1≤ai≤1091\le N\le 500,1\le a_i\le 10^91N500,1ai?109

思路

考虑当前每个集合大小为 sizsizsizsiz+1siz+1siz+1
显然 sizsizsiz 越大对我们越优
ai=num?siz+t(0≤t≤siz?1)a_i=num\cdot siz+t\quad (0\le t\le siz-1)ai?=num?siz+t(0tsiz?1)
那么要满足 num≥tnum\ge tnumt ,对于当前 aia_iai? 是合法的 但不一定是最优的
但是 sizsizsiz 范围是 1e91e91e9 ,于是不能每个都 O(n)O(n)O(n) 检验,考虑分块:

  1. siz≤nsiz\le\sqrt{n}sizn ? 时,那么 num≥n≥siz>tnum\ge\sqrt{n}\ge siz>tnumn ?siz>t,是合法的,我们就直接取 siz=nsiz=\sqrt{n}siz=n ? 让答案最大

  2. siz>nsiz> \sqrt{n}siz>n ? 时,那么 num<nnum<\sqrt{n}num<n ?,由于 sizsizsiz 太大,我们枚举 numnumnum
    应该满足 num≥t≥0num\ge t\ge 0numt0,于是有siz=?ainum?siz=\lfloor\frac{a_i}{num}\rfloorsiz=?numai???
    有一种额外情况: t=0t=0t=0
    此时 aia_iai? 一定为 numnumnum 的倍数,于是有 siz=ainum?1siz=\frac{a_i}{num}-1siz=numai???1 也是合法的

考虑当 siz>nsiz>\sqrt{n}siz>n ? 时候我们只需要检验 MinaMinaMina 即可
如果我们从小到大枚举 numnumnum,在 num≥nnum\ge \sqrt{n}numn ? 时候就会结束,总的次数在 n\sqrt{n}n ? 以内
考虑一组数据

2
1 100
51

证明不能按照上面的算

代码

#include<set>
#include<map>
#include<queue>
#include<stack>
#include<vector>
#include<cmath>
#include<cstdio>
#include<cstring>
#include<climits>
#include<cstdlib>
#include<iostream>
#include<algorithm>
using namespace std;
#define LL long long 
#define ULL unsigned long long 
int read(){
    bool f=0;int x=0;char c=getchar();while(c<'0'||'9'<c){
    if(c=='-')f=1;c=getchar();}while('0'<=c&&c<='9') x=(x<<3)+(x<<1)+(c^48),c=getchar();return !f?x:-x;
}
#define MAXN 500
#define INF 0x3f3f3f3f
LL ans;
int n,a[MAXN+5];
bool check(int x){
    x++,ans=0;for(int i=1;i<=n;i++){
    int k=a[i]/x,t=a[i]%x;if(!t){
    ans+=k;continue;}if(k+t<x-1)return 0;ans+=k+1;}return 1;
}
int main(){
    n=read();int Low=INF;for(int i=1;i<=n;i++)a[i]=read(),Low=min(Low,a[i]);for(int i=1;i<=Low;i++)if(check(Low/i)||check(Low/i-1)){
    //这里其实在里面加的1printf("%lld\n",ans);return 0;}return 0;
}

思考

这种题思维量极大,平时一定要注意锻炼思维