大力猜结论的贪心题。
先把 \(a\) 数组升序排序一下。
弄两个预处理数组。\(rich[i]\) 表示排序后前 \(i\) 个人中富人的个数,\(s[i]\) 表示排序后后 \(i\) 个人钱数的后缀和。
于是枚举 \(i=0,1,\cdots,n-1\),判断后 \((n-i)\) 个人平均分财产后的富人数量与当前的富人数量哪一个大。就这样一直打擂台下去就能找到最大化的富人数量了。
感性理解一下...这个贪心方法似乎是对的...
似乎我的做法跟别人的很不一样...不要 fst 錒(
Code:
记得开long long
。
#include <bits/stdc++.h>
#define ll long long
const char* chk[]={"NO","YES"};
using namespace std;
const int maxN=100005;
int n,x,a[maxN],rich[maxN];
ll s[maxN];
void solve();
int main() {
int t;scanf("%d",&t);
for (;t;t--) solve();
return 0;
}
void solve() {
memset(rich,0,sizeof rich);
memset(s,0,sizeof s);
// 多组数据,记得清空数组
scanf("%d%d",&n,&x);
for (int i=1;i<=n;i++) scanf("%d",&a[i]);
sort(a+1,a+n+1);
for (int i=1;i<=n;i++) rich[i]+=a[i]>=x;
for (int i=n;i;i--) s[i]=s[i+1]+a[i];
// 预处理 rich[] 和 s[] 数组
//printf("s[1]=%d\n",s[1]);
int ans=rich[n];
for (int i=0;i<n;i++) {
double get=1.0*s[i+1]/(n-i);
// get 表示后 (n-i) 个人总财产的平均数
//printf("get=%lf\n",get);
int now=rich[i];
if (get>=x) now+=n-i;
ans=max(ans,now); // 打擂台找最大化的富人数
//printf("now=%d\nans=%d\n",now,ans);
}
printf("%d\n",ans);
}
原文:https://www.cnblogs.com/Xray-luogu/p/12679325.html