Official

B - 工場の機械メンテナンス / Factory Machine Maintenance Editorial by MMNMM


メンテナンスをする順番を決めたとき、すべてのメンテナンスが終了するまでの所要時間 \(\displaystyle\sum _ {k=1} ^ {N-1}(T _ {p _ k} + R _ {p _ k})+T _ {p _ N}\) は、次のように変形できます。

\[\begin{aligned}\sum _ {k=1} ^ {N-1}(T _ {p _ k} + R _ {p _ k})+T _ {p _ N}&=\sum _ {k=1} ^ N(T _ {p _ k} + R _ {p _ k})-R _ {p _ N}\\&=\sum _ {k=1} ^ N(T _ k+R _ k)-R _ {p _ N}\end{aligned}\]

変形した後の第一項はメンテナンスする順番によりません。 第二項は最後にメンテナンスする機械 \(p _ N\) のみによります。 よって、最後にどの機械をメンテナンスするか決めれば、すべてのメンテナンスが終了するまでの所要時間が決まります。

式の形から、\(R _ {p _ N}\) が大きいほどすべてのメンテナンスが終了するまでの所要時間が短くなることがわかります。 よって、求める答えは \(R _ k\) が最大となる \(k\) 番目の機械を最後にメンテナンスするときの所要時間 \[\sum _ {k=1} ^ N(T _ k+R _ k)-\max _ kR _ k\] となります。 これを正しく計算することで、答えを求めることができます。

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

#include <iostream>
using namespace std;

int main() {
    int N;
    cin >> N;
    
    long sum = 0; // T+R の合計
    int max_R = 0; // R の最大値
    for (int i = 0; i < N; ++i) {
        int T, R;
        cin >> T >> R;
        sum += T + R;
        max_R = max(R, max_R);
    }
    
    // 合計から R の最大値を引いたものが答え
    cout << sum - max_R << endl;
    return 0;
}
N = int(input())

sum = 0 # T+R の合計
max_R = 0 # R の最大値
for i in range(N):
    T, R = map(int, input().split())
    sum += T + R
    max_R = max(R, max_R)

# 合計から R の最大値を引いたものが答え
print(sum - max_R)

posted:
last update: