洛谷 P2123 皇后游戏
题目链接
分析
显然 为最大值。
考虑使用邻项微扰,原本的第 项编号为 ,第 项编号为 。设前 项的 之和为 。
交换前,
交换后,。
若交换不会使得答案变得更优,即 。
这并不是一个合格的 偏序关系,因为没有 传递性,所以不能直接套用该关系作为比较函数进行排序。
进一步地推导,可以将该关系抽象为 。
将数据分成下标统一的两组 ,只需要比较两组之间的最小值即可。
1.
若 ,则 ;否则 。
2.
最小值一定为 之一,令 在 前。
3.
最小值一定为 之一,令 在 前。
4.
若 ,则 ;否则 。
这样一来,我们把整个序列分成两块,前面一块为 ,后面一块为 ;在块中的关系具有传递性。按照这种比较方式进行排序,可以确保 , 为 所在位置。
代码
#include <iostream>
#include <algorithm>
#include <ctime>
#include <string>
#include <vector>
#include <cmath>
using namespace std;
typedef long long ll;
const int maxn=2e5+10;
const ll INF=1LL<<60;
struct node {
int x,y;
bool s;
bool operator<(const node &b)const{
if (s!=b.s)
return s;
return s?x<b.x:y>b.y;
}
}p[maxn];
int read() {
int res=0,p=1;
char ch=getchar();
while(!isdigit(ch)) {
if (ch=='-')
p=-1;
ch=getchar();
}
while(isdigit(ch))
res=res*10+ch-'0',ch=getchar();
return res*p;
}
int main() {
int T=read();
while (T--) {
int n=read();
for (int i=1;i<=n;i++)
p[i].x=read(),p[i].y=read(),p[i].s=p[i].x<=p[i].y;
sort(p+1, p+1+n);
ll ans=p[1].x+p[1].y,sum=p[1].x;
for (int i=2;i<=n;i++) {
sum+=p[i].x;
ans=max(ans, sum)+p[i].y;
}
cout<<ans<<endl;
}
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】