Official
C - りんご収穫 / Apple Harvest Editorial
by
C - りんご収穫 / Apple Harvest Editorial
by
physics0523
尺取り法を使ってこの問題を解きます。
- 前準備として、 \(X\) を昇順にソートします。
- \(r=1,2,\dots,N\) について、以下の問題を解きます。
- 座標 \(X_l,X_{l+1},\dots,X_r\) にある木を全てカバーできるような最小の \(l\) はいくつか?
- この問題は、 \(X_r-X_l > K\) となっている限り \(l\) を増やし続けることで解くことができます。
- 最適解は、 \(r-l+1\) としてありうる最大値となります。
- \(r\) を増やしていくとき、この問題の答えの \(l\) が小さくならないことから尺取り法が適用可能です。具体的には、 \(r+1\) の求解を始める際に \(r\) に対しての \(l\) の解から始めることで、全体で \(l\) に対する加算を最大 \(N\) 回で済ませることができます。
時間計算量は \(O(N \log N)\) です(ソートがボトルネックになります)
実装例 (C++):
#include<bits/stdc++.h>
using namespace std;
int main(){
int N,K;
cin >> N >> K;
vector<int> X(N);
for(auto &nx : X){cin >> nx;}
sort(X.begin(),X.end());
int l=0,res=0;
for(int r=0;r<N;r++){
while(X[r]-X[l]>K){l++;}
res=max(res,r-l+1);
}
cout << res << "\n";
return 0;
}
posted:
last update:
