Description
皇后有 \(n\) 位大臣,每位大臣的左右手上面分别写上了一个正整数。恰逢国庆节来临,皇后决定为 \(n\) 位大臣颁发奖金,其中第 \(i\) 位大臣所获得的奖金数目为第 \(i-1\) 位大臣所获得奖金数目与前 \(i\) 位大臣左手上的数的和的较大值再加上第 \(i\) 位大臣右手上的数。
形式化地讲:我们设第 \(i\) 位大臣左手上的正整数为 \(a_i\),右手上的正整数为 \(b_i\),则第 \(i\) 位大臣获得的奖金数目为 \(c_i\) 可以表达为:
\[c_i=\begin{cases} a_1+b_1 & i=1 \\ max(c_{i-1},\sum_{j=1}^i a_j)+b_i & 2\leq i\leq n \end{cases}\]
当然,吝啬的皇后并不希望太多的奖金被发给大臣,所以她想请你来重新安排一下队伍的顺序,使得获得奖金最多的大臣,所获奖金数目尽可能的少。
注意:重新安排队伍并不意味着一定要打乱顺序,我们允许不改变任何一位大臣的位置。
Input
第一行包含一个正整数 \(T\) \((1\leq T\leq10)\),表示测试数据的组数。
接下来 \(T\) 个部分,每个部分的第一行包含一个正整数 \(n\) \((1\leq n\leq20000)\),表示大臣的数目。
每个部分接下来 \(n\) 行中,每行两个正整数,分别为 \(a_i\),\(b_i\) \((1\leq a_i,b_i\leq10^9)\),含义如上文所述。
Output
共 \(T\) 行,每行包含一个整数,表示获得奖金最多的大臣所获得的奖金数目。
Example
Input | Output |
---|---|
1 3 4 1 2 2 1 2 | 8 |
Input | Output |
---|---|
2 5 85 100 95 99 76 87 60 97 79 85 | 12 |
Solution
和 LuoguP1080 国王游戏 类似,采用贪心的策略。
考虑:若第 \(k\) 个大臣与第 \(k+1\) 个大臣交换位置后,两者间获得的较多奖金的一方的奖金减少。
设:排在第 \(k\) 个大臣前面的所有人的左手上的数的和为 \(s\) \((k=1,s=0)\),第 \(k-1\) 大臣的奖金为 \(c\) \((k=1,c=0)\),\(a_i\),\(b_i\) 依题设 ,
则有 \(max(max(c,s+a_{k+1})+b_{k+1},s+a_k+a_{k+1})+b_k<max(max(c,s+a_k)+b_k,s+a_k+a_{k+1})+b_{k+1}\)
我们先证明 \((1)\) \(max(x,z)<max(y,z)\) 作为交换 \(x\),\(y\) 的条件时与 \((2)\) \(x<y\) 等价:
若 \(x\geq y\),则不满足 \((1)\),\((2)\),不交换 \(x\),\(y\)
若 \(x<y\),则满足 \((2)\),交换 \(x\),\(y\),不满足 \((1)\),\((2)\)
综上,探究这类问题时,形如 \(max(x,z)<max(y,z)\) 的式子可化为 \(x<y\)
回到原题,
原式即 \(max(c-s,a_{k+1},a_k+a_{k+1}-b_{k+1})+s+b_k+b_{k+1}<max(c-s,a_k,a_k+a_{k+1}-b_k)+s+b_k+b_{k+1}\)
即 \(max(a_{k+1},a_k+a_{k+1}-b_{k+1})<max(a_k,a_k+a_{k+1}-b_k)\)
即 \(max(-a_k,-b_{k+1})<max(-a_{k+1},-b_k)\)
即 \((*)\) \(min(a_k,b_{k+1})>min(a_{k+1},b_k)\)
很遗憾,这并不是一个偏序关系,因为其不具有传递性。
举个栗子:\((3,5)\),\((1,1)\),\((1,7)\) 这个序列相邻的序偶均满足 \((*)\),而 \((1,1)\),\((1,7)\),\((3,5)\) 这样排序也满足 \((*)\),前者答案为 \(16\) ,后者答案为 \(14\) ,显然后者更优,我们如果单纯按照 \((*)\) 排序,无法保证结果的正确性。
实际上,我们可以在此之上进行一定的改良:
考虑 \((*)\) 不具有传递性的原因,当 \(min(a_k,b_{k+1})=min(a_{k+1},b_k)\) 时,不管我们交不交换,该条件均成立,这种不确定性会造成结果的不一致,这一点正是 \((*)\) 不具有传递性的原因。如在上面举出的栗子中,\((3,5)\) 和 \((1,1)\) 交换与否就影响了最后的结果,可以看出 \(a_i\) 和 \(b_i\) 的相对关系也会对最终的序列的顺序产生影响,我们不妨从如何消除这种影响开始考虑,既然 \(a_i\) 和 \(b_i\) 的相对关系会影响排序,那么我们可以按相对关系将序偶分组,组内排好序后再按组排序。
设:\(d_i=sgn(a_i-b_i)\),
首先,我们按 \(d_i\) 将序偶分成三组,
在同一组内,序偶之间不存在 \(a_i\) 和 \(b_i\) 的相对关系不一致的情况,易知在这种情况下 \((*)\) 具有传递性。具体来说就是:
对于 \(d_i=-1\) 的一组,若满足 \((*)\),则 \(a_k>a_{k+1}\),即按 \(a_i\) 升序排序即可
对于 \(d_i=0\) 的一组,则始终不满足 \((*)\),则无须排序
对于 \(d_i=1\) 的一组,若满足 \((*)\),则 \(b_{k+1}>b_k\),即按 \(b_i\) 降序排序即可
接下来考虑按组排序,
显然 \(d_i=0\) 的一组可以和其他的一组任意排序,那么我们将这一组放在中间即可
若 \(d_k=1\),\(d_{k+1}=-1\),则必满足 \((*)\),则 \(d_i=-1\) 的一组应放在 \(d_k=1\) 的一组的前面
如此,我们便得到了最终的序列,再遍历所有大臣求最大的奖金即可。
Code
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef struct{
int a,b,d;
}h_type;
const int n_size=20005;
int T,n;
ll c[n_size];
h_type h[n_size];
bool cmp(h_type &x,h_type &y);
int main(void){
scanf("%d",&T);
for(int i=1;i<=T;i++){
scanf("%d",&n);
for(int j=1;j<=n;j++){
scanf("%d%d",&h[j].a,&h[j].b);
if(h[j].a==h[j].b) h[j].d=0;
else if(h[j].a<h[j].b) h[j].d=-1;
else h[j].d=1;
}
sort(h+1,h+n+1,cmp);
ll sum=0;
for(int j=1;j<=n;j++){
sum+=h[j].a;
c[j]=max(c[j-1],sum)+h[j].b;
}
printf("%lld\n",c[n]);
}
return 0;
}
bool cmp(h_type &x,h_type &y){
if(x.d!=y.d) return x.d<y.d;
if(x.d==-1) return x.a<y.a;
if(x.d==1) return x.b>y.b;
return false;
}