[CF1602F/1601D] Difficult Mountain


前言

update 2021.11.1 我本以為紫名就不用打 Div2 了,沒想到有 Div2 上限是2100,但是可以打 Div1 了,好耶ヾ(✿゚▽゚)ノ

難得的陽間比賽(指比賽時間),上大分!

雖然今天下午狀態還行,可惜最后一場 Div2 沒能AK,不過竟然上榜了!人生首次!

而且還是通過 Hack 了一個人從 rank5 翻到了 rank4,與機房大佬三連了。(rank2,3,4)

首次使用 Hack,體驗極佳,下次繼續。

所以水題解。

題目

CF

題目大意:

\(n\) 位登山者和一座初始困難度為 \(d\) 的山,每位登山者有兩個值 \(s_i,a_i\) 表示TA的技能點和邋遢度。

登山者 \(i\) 可以登山的前提是其困難度不超過 \(s_i\),當登山者 \(i\) 成功登山后,困難度會變為 \(\max(d,a_i)\)

你需要找到一個合適的登山順序以保證有最多的人成功登山,輸出最大人數。

\(1\le n\le 5\times 10^5;0\le d,s_i,a_i\le 10^9.\)

講解

這個貪心真的NB,完全想不到,但是知道了之后直呼NB!

直接按 \(\max(s_i,a_i)\) 的大小排序,如果相等按 \(s_i\) 大小排序,然后直接登山即可。

簡單分類討論一下:

  1. \(s_i<a_j\),這里指的是 \(i\) 的最大值為 \(s_i\)\(j\) 的最大值為 \(a_j\),下同。此時如果把 \(j\) 放前面,\(j\) 如果成功上山,那么 \(i\) 一定上不了,不如先讓 \(i\) 試試,不優。
  2. \(a_i<s_j\),強的留在后面總是不劣的。
  3. \(s_i<s_j\),同理不劣。
  4. \(a_i<a_j\),此時 \(j\) 如果上山,\(i\) 一定上不了山,顯然取邋遢度小的在前更優。

取等情況其實也差不多是這些思路,這道題就當繳智商稅了。

時間復雜度 \(O(n\log_2n)\),瓶頸在排序。

還有碼量較大的線段樹優化DP做法,這里就不說了。

代碼

超短代碼
//12252024832524
#include <bits/stdc++.h>
#define TT template<typename T>
using namespace std;

typedef long long LL;
const int MAXN = 500005;
int n,d;
int s[MAXN],a[MAXN],p[MAXN];

LL Read()
{
	LL x = 0,f = 1; char c = getchar();
	while(c > '9' || c < '0'){if(c == '-') f = -1;c = getchar();}
	while(c >= '0' && c <= '9'){x = (x*10) + (c^48);c = getchar();}
	return x * f;
}
TT void Put1(T x)
{
	if(x > 9) Put1(x/10);
	putchar(x%10^48);
}
TT void Put(T x,char c = -1)
{
	if(x < 0) putchar('-'),x = -x;
	Put1(x); if(c >= 0) putchar(c);
}
TT T Max(T x,T y){return x > y ? x : y;}
TT T Min(T x,T y){return x < y ? x : y;}
TT T Abs(T x){return x < 0 ? -x : x;}

int main()
{
//	freopen(".in","r",stdin);
//	freopen(".out","w",stdout);
	n = Read(); d = Read();
	for(int i = 1;i <= n;++ i) s[i] = Read(),a[i] = Read(),p[i] = i;
	sort(p+1,p+n+1,[](int x,int y){
		if(Max(s[x],a[x]) ^ Max(s[y],a[y])) return Max(s[x],a[x]) < Max(s[y],a[y]);
		return s[x] < s[y];
	});
	int ans = 0;
	for(int i = 1;i <= n;++ i)
		if(s[p[i]] >= d) ++ans,d = Max(d,a[p[i]]);
	Put(ans,'\n');
	return 0;
}

后記

有老哥按 \(a_i+s_i\)\(a_i\times s_i\) 排序,都過了!/jk

update ? 也可以用類似上面的方法證明。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM