P11960 [GESP202503 五级] 平均分配 贪心+模拟

P11960 [GESP202503 五级] 平均分配
这个题我的贪心策略就是先尽可能的拿大的。
拿完之后如果他们数目相等,那肯定就直接输出了。
如果数目不相等的话,那肯定是要把一个大的换成一个小的。
那么这时候怎么换才是更优的呢?从贪心的来看,肯定是从大的换小的,a和b的差值更小的更优,因为这样子可以减少的更少,所以在这里用小根堆维护。
这里的小根堆有两个参数,第1个是表示他们的差值,第2个如果为1的话表示a>b,为2的话表示b>a,在取出的时候需要看一下第2个的标识判断是不是我们需要的,在a数组里面取多了的时候就需要把a拿出来,此时op == 1。

#include<bits/stdc++.h>
using namespace std;
const int N = 2e5+100;
#define int long long
#define pii pair<int,int>
#define x first
#define y second
int n;
int b[N],a[N];
signed main()
{
    cin>>n;
    int sum1 = 0,sum2 = 0;
    int ans = 0;
    priority_queue<pii,vector<pii>,greater<pii> >q;
    for(int i = 1 ; i <= 2*n ; ++i)cin>>a[i];
    for(int i = 1 ; i <= 2*n ; ++i)cin>>b[i];
    for(int i = 1 ; i <= 2*n ; ++i)
    {
        ans += max(a[i],b[i]);
        if(a[i] > b[i]){
            sum1++;q.push({a[i]-b[i],1});
        }
        else{
            sum2++;q.push({b[i]-a[i],2});
        }
    }
    if(sum1 == sum2){
        cout<<ans<<endl;
    }
    else{
        int op;
        op = (sum1 > sum2 ? 1 : 2);
//         cout<<op<<endl;
        while(q.size() && sum1 != sum2)
        {
            int dis = q.top().x,now = q.top().y;
//             cout<<dis<<" "<<now<<endl;
            q.pop();
            if(now != op)continue;
            ans -= dis;
            if(op == 1)sum1--,sum2++;
            else sum1++,sum2--;
        }
        cout<<ans<<endl;
    }
    return 0;
}
posted on 2026-02-12 20:58  钟一一  阅读(70)  评论(0)    收藏  举报