CF1393C(贪心,整除均分)

CF1393C(贪心,整除均分)

题意

给一个序列 \(a\) ,对其排列,要求两个相同数字之间距离的最小差最大。

思路

看形式想到二分,但check()并不好写。

相邻差有关的问题,如果可以缩小问题规模的能考虑dp或者贪心,本题安排整个序列,不好找子问题dp就算了,然后就是“不是递推地贪心”(递推的贪心其实就是dp了)。剩下的常见套路就是找序列一些值(比如出现次数之类的)+数学搞出来贪心的判断。这里相邻差的贪心思路是找到众数整除均分。


我们把众数种类设为 \(sum\) 。整个序列长度为 \(n\) 。可以按均分的思路得到解形式如下:

\[[a,b](...)[a,b](...)[a,b](.) \]

按整除的意义就是均分,我们均分剩下数字道 \(()\) 里。设众数出现 \(mx\)

就是 \(\frac{n - sum * cnt}{mx - 1}\) 。这个整除就算出来最小桶容量也就是最小分配长度,之后再加上 \(sum-1\) 这个\([]\) 中数字长度就是答案。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#include<set>
#include<queue>
#include<map>
#include<stack>
#include<string>
#include<random>
#include<iomanip>
#define yes puts("yes");
#define inf 0x3f3f3f3f
#define ll long long
#define linf 0x3f3f3f3f3f3f3f3f
#define ull unsigned long long
#define endl '\n'
#define int long long
#define rep(i,a,n) for(int i = a;i <= n;i++)
#define per(i,n,a) for(int i = n;i >= a;i--)
using namespace std;
mt19937 mrand(random_device{}());
int rnd(int x) { return mrand() % x;}
typedef pair<int,int> PII;
const int MAXN =10 + 2e5 ,mod=1e9 + 7;

void solve()
{    
    int n; cin >> n;
    vector<int> a(n + 1);
    vector<int> cnt(n + 1);
    for(int i = 1;i <= n;i += 1) {
        cin >> a[i];
        cnt[a[i]] += 1;
    }
    int mx = *max_element(cnt.begin(),cnt.end());
    int sum = count(cnt.begin(),cnt.end(),mx);
    cout << (n - sum * mx) / (mx - 1) + sum - 1 << endl;
}
signed main()
{
    ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);

    int T;cin>>T;
    while(T--)
        solve();

    return 0;
}
posted @ 2022-07-15 13:00  Mxrurush  阅读(35)  评论(0编辑  收藏  举报