思路:
大水题,然而题面太难读懂了。。。。
(一开始读错题面差点爆0,最后悟错题意又差点改成错的)
这道题其实是一个3条件选择问题
第一优先级为乙方选中的x最大
第二优先级为乙方弃用(s-t)个人的y的和最大
第三优先级为x的和最大
我们一个一个考虑
针对第一优先级,我们先以y排一遍序
找出y最小的(s-t)的,默认选上(他们是替死鬼,不管和谁配,永远不会被a选上)
之后按x排序,选出最大的t个,同时记下这t个中最小的y,记做minx
就可以保证被乙方选到的x的和最大
下一步考虑(s-t)的y的和
我们已经有替死鬼卡着,让乙必选我们挑的那些
于是我们把剩下的再按y排序
如果y<minx,则加进去后不影响乙方的选择
我们就可以替换替死鬼
答案的话中间记录就好咯
代码:
#include<iostream> #include<cstdio> #include<algorithm> #include<queue> #define rii register int i using namespace std; struct pst{ long long x,y; }pe[100005]; //bool operator > (pst lk,pst kl) //{ // return lk.x<kl.x; //} long long ans,n,s,t; priority_queue<long long> q; bool cmp1(pst lk,pst kl) { if(lk.y==kl.y) { return lk.x<kl.x; } return lk.y<kl.y; } bool cmp2(pst lk,pst kl) { if(lk.x==kl.x) { return lk.y>kl.y; } return lk.x>kl.x; } bool cmp3(pst lk,pst kl) { if(lk.y==kl.y) { return lk.x>kl.x; } return lk.y>kl.y; } int main() { scanf("%lld%lld%lld",&n,&s,&t); for(rii=1;i<=n;i++) { scanf("%lld%lld",&pe[i].x,&pe[i].y); } long long ans1=0,ans2=0; long long del=s-t; sort(pe+1,pe+n+1,cmp1); for(rii=1;i<=del;i++) { ans1+=pe[i].x; ans2+=pe[i].y; } sort(pe+1+del,pe+n+1,cmp2); long long minx=19260817; for(rii=del+1;i<=del+t;i++) { ans1+=pe[i].x; ans2+=pe[i].y; minx=min(minx,pe[i].y); } sort(pe+s+1,pe+n+1,cmp3); int cnt=0,head=0; for(rii=del+t+1;i<=n;i++) { if(pe[i].y<minx&&cnt<del) { cnt++; head++; ans1+=pe[i].x; ans2+=pe[i].y; ans1-=pe[head].x; ans2-=pe[head].y; } } printf("%lld %lld",ans1,ans2); // for(rii=1;i<=n;i++) // { // cout<<pe[i].y<<" "; // }pe[5].y }