1. 程式人生 > 實用技巧 >洛谷P4552 [Poetize6] IncDec Sequence 題解 差分陣列

洛谷P4552 [Poetize6] IncDec Sequence 題解 差分陣列

題目連結:https://www.luogu.com.cn/problem/P4552

解題思路:設差分陣列 \(d[i] = a[i] - a[i-1]\),用 \(sump\) 表示所有 \(\gt 0\)\(d[i]\) 之和;用 \(sumn\) 表示所有 \(\lt 0\)\(d[i]\) 的絕對值之和。

則因為一開始需要操作的是儘可能地消掉一個差分陣列中的 \(+1\)\(-1\)。後期只需要消掉一個 \(+1\)\(-1\) 即可。所以:

  • 最少操作次數為 \(\max \{ sump, sumn \}\)
  • 結果數為 \(|sump - sumn| + 1\)

示例程式碼:

#include <bits/stdc++.h>
using namespace std;
const int maxn = 100010;
long long n, a[maxn], d[maxn], sump, sumn;
int main() {
    cin >> n;
    for (int i = 1; i <= n; i ++) cin >> a[i];
    for (int i = 2; i <= n; i ++) {
        d[i] = a[i] - a[i-1];
        if (d[i] > 0) sump += d[i];
        else sumn += abs(d[i]);
    }
    cout << max(sump, sumn) << endl << abs(sump - sumn) + 1 << endl;
    return 0;
}

再簡化一些的程式碼:

#include <bits/stdc++.h>
using namespace std;
const int maxn = 100010;
long long n, a[maxn], d, sump, sumn;
int main() {
    cin >> n;
    for (int i = 1; i <= n; i ++) cin >> a[i];
    for (int i = 2; i <= n; i ++) {
        d = a[i] - a[i-1];
        if (d > 0) sump += d;
        else sumn += abs(d);
    }
    cout << max(sump, sumn) << endl << abs(sump - sumn) + 1 << endl;
    return 0;
}