NC53681「土」巨石滾滾
題目描述
帕秋莉掌握了一種土屬性魔法
她使用這種魔法建造了一個大型的土球,並讓其一路向下去衝撞障礙
土球有一個穩定性x,如果x < 0,它會立刻散架
每衝撞一個障礙,土球會喪失ai的穩定性,衝撞之後,又會從障礙身上回饋bi的穩定性
帕秋莉想知道,如果合理的安排障礙的順序,在保證土球不散架的情況下,是否可以將障礙全部撞毀呢?
輸入描述
輸入一個整數T,代表T組數據,每組數據中:
前一行兩個整數n , m,表示障礙個數和土球的穩定性
接下來一行兩個整數,分別表示障礙的ai和bi
輸出描述
若可以,輸出“Yes”(不含引號),否則輸出“No”(不含引號)
輸入樣例
1
5 50
49 49
52 0
5 10
26 24
70 70
輸出樣例
No
思路:
這題。。。。很顯然的貪心。。但是無論我怎麼設計貪心總是有東西沒考慮到。。看了大佬的思路,大佬提供了一種考慮很周全的思路。分段貪心。對於每個,我們可以求一下它的增量。然後對增量以爲中點分段,我們先對增量降序,對於的部分我們一定可以使得變得更大,但是有可能會使得得不到最優值,我們需要對這部分的升序,對於,這一部分我們已經拿不到額外的利益了,爲了使得最優,我們要讓儘可能的小,儘可能大,所以對於部分對降序就好了。
代碼:
#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e6 + 10;
typedef long long int ll;
struct node{
ll x,y,z;
node(){}
node(ll a,ll b,ll c = 0):x(a),y(b),z(b - a){}
};
node a[maxn];
bool cmp(node a,node b){
return a.z > b.z;
}
bool cmp1(node a,node b){
return a.x < b.x;
}
bool cmp2(node a,node b){
return a.y < a.y;
}
void solved(){
int t;cin>>t;
while(t--){
ll n,m;cin>>n>>m;
int cnt = 0;
for(int i = 1; i <= n; i++){
ll x,y;cin>>x>>y;
a[i].x = x;a[i].y = y;
a[i].z = y - x;
if(a[i].z > 0)cnt++;
}
if(cnt == n){
cout<<"Yes"<<endl;continue;
}
sort(a + 1,a + 1 + n,cmp);
sort(a + 1,a + 1 + cnt,cmp1);
sort(a + 1 + cnt,a + 1 + n,cmp2);
for(int i = 1; i <= n; i++){
m -= a[i].x ;
if(m < 0)break;
m += a[i].y;
}
if(m > 0)cout<<"Yes"<<endl;
else cout<<"No"<<endl;
}
}
int main(){
solved();
return 0;
}