CF1334B - Middle Class 題解

大力猜結論的貪心題。
先把 \(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);
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章