CF 1612 E

看到k等于20 我们大胆猜测这个选择的个数不会超过20条
枚举我们要选i条 然后计算权值的话 要是大于等于i的k都是算1的
否则就算 k/i
我们按照这个给每一个计算一下权值 选最大的i条即可

void solve(){
    int n;cin>>n;
    vector<int>t[21],cz[21],v(200010);
    for(int i=1;i<=n;i++){
        int a,b;cin>>a>>b;
        v[a]+=b;
        t[b].push_back(a);
    }
    int ans_s=0,ans_x=1;
    vector<int>now(200010),now1(200010);
    for(int i=20;i>=1;i--){
        for(auto j:t[i]){
            now[j]+=1;
            now1[j]+=i;
        }
        vector<PII>d;
        for(int j=1;j<=2e5;j++)if(now[j]&&now[j]*i+(v[j]-now1[j]))d.push_back({now[j]*i+(v[j]-now1[j]),j});
        for(int j=1;j<=2e5;j++)if(!now1[j]&&v[j])d.push_back({v[j],j});
        sort(all(d),greater<>());
        int res=0;
//        cout<<i<<endl;
        for(int j=0;j<min(i,(int)d.size());j++){
            res+=d[j].first;
//            cout<<d[j].first<<' '<<d[j].second<<endl;
            cz[i].push_back(d[j].second);
        }
        if(ans_s*i<res*ans_x&&cz[i].size()==i){
            ans_s=res;
            ans_x=i;
        }
//        cout<<i<<' '<<res<<endl;
    }
    cout<<ans_x<<endl;
    for(auto i:cz[ans_x])cout<<i<<' ';
}
posted @ 2023-12-13 16:43  ycllz  阅读(13)  评论(0)    收藏  举报