[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\) 的大小关系进行分组,进行组内排序和组外排序:
- \(a_i<b_i\),此时原不等式等价于 \(a_i<a_j\),因此按 \(a\) 降序排序。
- \(a_i=b_i\),随便排就行。
- \(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;
}