题解:P14593 猫猫虫打 CF
看完题之后感觉是水贪心。
题意简述
初始能力值 \(x=0\) 且有 \(n\) 场比赛,当 \(x \leq a_i\) 时可以打第 \(i\) 场比赛,并将能力值更新为 \(\max (b_i,x)\)。
求最多可参与比赛的场数。
换言之,所谓 \(a_i\) 其实是参与第 \(i\) 场比赛的能力值上限,而 \(b_i\) 是参与第 \(i\) 场比赛后用于更新能力值的数据。
思路
不难想到去使打完每一场比赛后的能力值 \(x\) 尽可能小,并且把能力值上限 \(a_i\) 的比赛放到前面先打。
同时尽量满足这两个条件,不难想到按照 \(\max (a_i,b_i)\) 升序排序。
- 当 \(\max (a_i,b_i) < \max (a_j,b_j)\) 时,如果先打了第 \(j\) 场,要么 \(a_i < b_j\) 则少打了一场,要么 \(b_i < a_j\) 则没有影响。由此可得需要将 \(\max (a_i,b_i)\) 较小者放在前面。
- 下面都讨论 \(\max (a_i,b_i) = \max (a_j,b_j)\) 时的情形。当 \(a_i<a_j\) 时,显然可以把上限较高的留到后面再打。
- 最后,其余情况均一样时,显然是尽量先打 \(b_i\) 小的比赛会使得结果更优。
然后得出排序优先级:先依据 \(\max (a_i,b_i) < \max (a_j,b_j)\) 排序,然后依据 \(a_i<a_j\) 最后是 \(b_i<b_j\) 排序。
最后对排序完成后的数据根据题意模拟即可。时间复杂度主要在于排序的 \(\Theta (n \log n)\)。
代码
#include<bits/stdc++.h>
#define ll long long
#define ios ios::sync_with_stdio(0),cin.tie(0),cout.tie(0)
using namespace std;
const int N=1000005;
int n,ans;
ll x;
struct node {
ll a,b,Max;
}f[N];
bool cmp(node p,node q) {
if(p.Max!=q.Max)return p.Max<q.Max;
if(p.a!=q.a)return p.a<q.a;
return p.b<q.b;
}
int main() {
ios;cin>>n;
for(int i=1;i<=n;i++) {
cin>>f[i].a>>f[i].b;
f[i].Max=max(f[i].a,f[i].b);
}
sort(f+1,f+1+n,cmp);
for(int i=1;i<=n;i++)if(x<=f[i].a)ans++,x=max(x,f[i].b);
cout<<ans<<'\n';
return 0;
}
完结撒花。
本文来自博客园,作者:Circle_Table,转载请注明原文链接:https://www.cnblogs.com/Circle-Table/articles/19271411

浙公网安备 33010602011771号