公式

B - 高速道路の料金所 / Highway Toll Booth 解説 by MMNMM


求めるものは、\(i=1,2,\ldots,N-K+1\) に対する \(G+T _ 1+T _ 2+\cdots+T _ {i-1}+T _ {i+K}+\cdots+T _ N\) のうち最大のものの値です。

\((T _ i) _ {1\le i\le N}\) の累積和 \(S _ i=T _ 1+T _ 2+\cdots+T _ {i-1}\ (1\le i\le N+1)\) を事前に計算しておくことで、それぞれの \(i\) に対する値を定数時間で求めることができます。

実装例は以下のようになります。

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

int main() {
    int N, K, G;
    cin >> N >> K >> G;

    vector<long> T(N);
    for (long& t : T) {
        int d; // d の値は使わないので、読むだけ読んで何もしない
        cin >> d >> t;
    }

    for (int i = 1; i < N; ++i) {
        T[i] += T[i - 1]; // 累積和を計算する
    }
    T.emplace(T.begin()); // 先頭に 0 を追加しておく

    long ans = G + T[N];
    for (int i = 0; i + K <= N; ++i) {
        ans = min(ans, G + T[i] + T[N] - T[i + K]); // i から i+K までを ETC 利用区間にしたときの答えを求める
    }
    cout << ans << endl;

    return 0;
}
N, K, G = map(int, input().split())

T = [int(input().split()[1]) for i in range(N)] # D の値は使わないので、読まない

for i in range(1, N):
    T[i] += T[i - 1] # 累積和を計算する
T = [0] + T # 先頭に 0 を追加しておく

ans = G + T[-1]
for i in range(N - K + 1):
    ans = min(ans, G + T[i] + T[N] - T[i + K]) # i から i+K までを ETC 利用区間にしたときの答えを求める

print(ans)

投稿日時:
最終更新: