公式
C - 本棚の整理 / Organizing the Bookshelf 解説
by
C - 本棚の整理 / Organizing the Bookshelf 解説
by
kyopro_friends
この問題は尺取法により解くことができます。
尺取法の基本的な枠組みは以下の通りでした。
while left < N:
while rightを追加してもOK:
rightを追加
right+=1
/*区間 [left, rihgt) に対するなんらかの処理*/
leftを縮める
left+=1
今回の問題では、「rightを追加してもOKか?」の判定のために \(B\) に関する和が、問題に対する答え「面白さの和は?」を求めるために \(A\) に関する和が必要なので、その両方持ちながら尺取法を行えばよいです。
計算量は \(O(N)\) です。
以下の実装例では、 \(l>r\) となる瞬間も存在しますが、今回の問題に対しては正しく動作することを証明できます。
実装例 (C++)
#include<bits/stdc++.h>
using namespace std;
int main(){
int n;
long long k;
cin >> n >> k;
vector<int>a(n), b(n);
for(int i=0; i<n; i++) cin >> a[i];
for(int i=0; i<n; i++) cin >> b[i];
long long sum_a = 0, sum_b = 0, ans = 0;
int r = 0;
for(int l=0; l<n; l++){
while(r < n && sum_b + b[r] <= k){
sum_b += b[r];
sum_a += a[r];
r++;
}
ans = max(ans, sum_a);
sum_b -= b[l];
sum_a -= a[l];
}
cout << ans << endl;
}
実装例 (Python)
N, K = map(int, input().split())
A = list(map(int, input().split()))
B = list(map(int, input().split()))
sum_A = 0
sum_B = 0
r = 0
ans = 0
for l in range(N):
while r < N and sum_B + B[r] <= K:
sum_B += B[r]
sum_A += A[r]
r += 1
ans = max(ans, sum_A)
sum_B -= B[l]
sum_A -= A[l]
print(ans)
投稿日時:
最終更新:
