洛谷 P2123 皇后游戏 解题报告

P2123 皇后游戏

题意:

给定\(T\)组长为\(n\)\(A\),\(B\)数组和\(C\)的计算方法,求一种排列方法,使最大的\(C\)最小化。

数据范围:

\(1 \le T \le 10,1 \le n \le 20000,1 \le A_i,B_i \le 10^9\)


其实这种题基本可以通过求邻项交换来贪心了(上午还想错了)

分析一下我们可以知道最大的C即是最后一项\(C\),如果我们只考虑最后两个项\(c_1,c_2\),我们可以找到一个最优方法。

但事实上,对任意两项,我们都可以找到一个方法使它们某一项放在后面的位置时 在后面的\(C\)更小

如果以此种方法为关键字进行排序,就可以得到最优解了。

这个方法就不写具体推导了,还是要自己推为好。


Code:

#include <cstdio>
#include <algorithm>
#define ll long long
ll max(ll x,ll y){return x>y?x:y;}
ll min(ll x,ll y){return x<y?x:y;}
const int N=20010;
struct node
{
    ll a,b;
    bool friend operator <(node n1,node n2)
    {
        return min(n1.a,n2.b)<min(n1.b,n2.a);
    }
}d[N];
ll c[N];
int n,t;
int main()
{
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
            scanf("%lld%lld",&d[i].a,&d[i].b);
        std::sort(d+1,d+1+n);
        c[1]=d[1].a+d[1].b;
        ll f=d[1].a;
        for(int i=2;i<=n;i++)
        {
            f+=d[i].a;
            c[i]=max(c[i-1],f)+d[i].b;
        }
        printf("%lld\n",c[n]);
    }
    return 0;
}


2018.7.23

posted @ 2018-07-23 14:53  露迭月  阅读(157)  评论(0编辑  收藏  举报