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;
}
浙公网安备 33010602011771号