[luogu2123] 皇后游戏

那她既然都说到老国王了,那肯定就是贪心了。

先声明两个引理:

引理1:若 \(\max(c,a)<\max(c,b)\) 时,定有 \(a<b\)

引理2:\(\max(a,b)-a-b=-\min(a,b)\)

证明就不说了,非常好证。

考虑 \(i,j\) 两大臣孰先孰后,假如 \(i\) 在前面更优,\(x\) 表示所有在他们前面的大臣的 \(\sum a\)\(y\) 表示在他们前面的第一名大臣的 \(c\) 值,则有:

\[\max(max(y,x+a_i)+b_i,x+a_i+a_j)+b_j<\max(max(y,x+a_j),x+a_j+a_i)+b_i \]

\[\max(y+b_i+b_j,x+a_i+b_i+b_j,x+a_i+a_j+b_j)<\max(y+b_i+b_j,x+a_j+b_i+b_j,x+a_i+a_j+b_i) \]

\[\max(x+a_i+b_i+b_j,x+a_i+a_j+b_j)<\max(x+a_j+b_i+b_j,x+a_i+a_j+b_i)(引理1) \]

\[\max(b_i,a_j)+a_i+b_j<\max(b_j,a_i)+a_j+b_i \]

\[\max(b_i,a_j)-b_i-a_j<\max(b_j,a_i)-b_j-a_i \]

\[-\min(b_i,a_j)<-\min(b_j,a_i)(引理2) \]

\[\min(b_i,a_j)>min(b_j,a_i) \]

到这里已经不能再化简了,但是该式不具有可传递性。

考虑按照 \(a_i\)\(b_i\) 的大小关系进行分组,进行组内排序和组外排序:

  1. \(a_i<b_i\),此时原不等式等价于 \(a_i<a_j\),因此按 \(a\) 降序排序。
  2. \(a_i=b_i\),随便排就行。
  3. \(a_i>b_i\),此时原不等式等价于 \(b_i>b_j\),因此按 \(b\) 升序排序。

关于组外排序,若 \(i\) 属于第一组,\(j\) 属于第二组,则有 \(b_i>a_i\),成立,因此第一组在第二组前,化简原理类似于引理1。

同理,第二组在第三组前。

那直接排序,然后依题意模拟即可。时间复杂度 \(O(n\log n)\)

#include<bits/stdc++.h>
#define int long long
using namespace std;
int n;
struct hand{
	int a,b;
}peo[20005];
int d(hand x){
	if(x.a==x.b) return 0;
	return ((x.a>x.b)?1:-1);
}int cmp(hand x,hand y){
	if(d(x)!=d(y)) return d(x)<d(y);
	if(d(x)>0) return x.b>y.b;
	return x.a<y.a;
}void solve(){
	cin>>n;
	for(int i=1;i<=n;i++)
		cin>>peo[i].a>>peo[i].b;
	sort(peo+1,peo+n+1,cmp);
	int s=0,c=0;
	for(int i=1;i<=n;i++){
		s+=peo[i].a;
		c=max(c,s)+peo[i].b;
	}cout<<c<<"\n";
}signed main(){
	ios::sync_with_stdio(0);
	cin.tie(0),cout.tie(0);
	int t;cin>>t;
	while(t--) solve();
	return 0;
} 
posted @ 2024-11-10 16:13  长安一片月_22  阅读(8)  评论(0编辑  收藏  举报