#746. 排列

#746. 排列

题目描述

有N个骑士, 他们的初始攻击力分别为 \(a_1, a_2, ... , a_n\). 并且每个骑士都有一个增益能力 \(b_i\).

对于每个骑士, 他都会选择一名其他骑士(不包含自己), 使被选择骑士的攻击力增加 \(b_i\).

判断是否有一种骑士的排列, 不管骑士如何选择增益的对象, 都满足骑士的攻击力从左到右是不增的.

输入格式

第一行一个正整数 T, 表示数据组数.

对于每组数据 第一行一个正整数 N, 表示骑士的个数

接下来 N 行, 每行两个整数. 第 i 行表示 \(a_i\)\(b_i\). 即骑士i的初始攻击力和增益能力.

输出格式

对于每组数据, 如果能存在一种排列骑士的方案满足要求, 就输出 Yes.

否则 输出 No.

数据范围

对于所有数据, 满足 \(1 \leq T \leq 1000, 2 \leq N \leq 100, 0 \leq a_i, b_i \leq 10^6\).

样例输入

3
2
15 25 
10 5 
3
7 0 
7 3 
10 0 
3
10 10 
20 20 
30 30

样例输出

Yes
Yes
No

样例解释

对于第一组数据, 由于 N = 2, 所以骑士的攻击力最后一定有 35, 20. 显然存在方案.

对于第二组数据, 我们可以构造骑士排列为 10, 7, 7 其中增益能力为 3 的骑士放在最后一个. 这样一来无论增益能力为 3 的骑士如何选择, 都满足要求.

对于第三组数据, 我们可以证明没有满足要求的方案, 于是输出 No.

题目分析

如果存在方案成立,必定满足\(a_i\)无论加了多少增益,都\(≥a_{i+1}\),即使什么增益都不加也满足,因此成立的方案一定有且仅有倒序排序之后的。

我们使用\(a_i\)的最大值(加上了所有的\(b_i\))与\(a_{i+1}\)的最小值(什么都不加)进行比较,所有i都成立即可说明满足需求。

AC code

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
struct Node{
    ll x,y;
}a[120];
bool cmp(Node a, Node b) {
    if(a.x == b.x)
        return a.y > b.y;
    return a.x < b.x;
}
int main() {
    int tc;
    scanf("%d",&tc);
    while(tc--) {
        int n;
        scanf("%d",&n);
        
        ll sum = 0;
        for(int i = 1 ; i <= n ; i++) {
            scanf("%lld%lld",&a[i].x,&a[i].y);
            sum+=a[i].y;
        }
        if(n==2) {
            puts("Yes");
            continue;
        }
        sort(a+1,a+n+1,cmp);
        bool flag = 1;
        for(int i = 1 ; flag && i <= n-1 ; i++) {
            //查加上所有是否比前面大
            //满状态vs0状态
            if(a[i].x+sum-a[i].y > a[i+1].x)
                flag = 0;
        }
        if(flag)
            puts("Yes");
        else puts("No");
    }
}
posted @ 2022-04-18 22:47  seekerHeron  阅读(37)  评论(0)    收藏  举报