cf1267J

题意简述:给出n个APP的种类,你要用屏幕来安置这n个APP,屏幕大小由你确定,同一种APP只能放在一个屏幕中,并且一个屏幕要么被放慢,要么离放慢差一个

要你求出最少需要多少个屏幕,不需要输出屏幕大小(屏幕大小由你确定)n<=2e5

题解:屏幕大小不会超过所有种类中APP数目最少的那种,因此暴力枚举屏幕大小,计算就好,复杂度cnt[1]*k,k为种类,因为cnt[1]*k<=cnt[1]+cnt[2]+...cnt[k]<=n,所以复杂度O(n)

#include<bits/stdc++.h>
#define forn(i, n) for (int i = 0 ; i < int(n) ; i++)
#define fore(i, s, t) for (int i = s ; i < (int)t ; i++)
#define fi first
#define se second
#define all(x) x.begin(),x.end()
#define pf2(x,y) printf("%d %d
",x,y)
#define pf(x) printf("%d
",x)
#define each(x) for(auto it:x)  cout<<it<<endl;
#define pii pair<int,int>
using namespace std;
typedef long long ll;
const int maxn=2e6+5;
const int maxm=2e5+5;
const int inf=1e9;
int n,cnt[maxn];
void solve(){
	int n;
	cin>>n;
	for(int i=1;i<=n;i++)
		cnt[i]=0;
	for(int i=0;i<n;i++){
		int x;
		scanf("%d",&x);
		cnt[x]++;
	}
	vector<int> a;
	for(int i=1;i<=n;i++)
		if(cnt[i]) a.push_back(cnt[i]);
	sort(all(a));
	int ans=1e9;
	for(int i=2;i<=a[0]+1;i++){
		int sum=0;
		for(auto x:a){
			if(x%i==0) sum+=x/i;
			else {
				if(x/i>=i-x%i-1) sum+=x/i+1;
				else {
					sum=1e9;break;
				}
			} 
		}
		//pf(sum);
		ans=min(ans,sum);
	}
	cout<<ans<<endl;
}
int main(){
	int t;
	cin>>t;
	while(t--)
		solve();
}

  

原文地址:https://www.cnblogs.com/033000-/p/12378538.html