[CF596B] Wilbur and Array
題目大意
有個序列 $a_1, a_2, \ldots, a_n$,目標是經過某些操作把它變成 $b_1, b_2, \ldots, b_n$。每一次可以進行的操作是:選一個 $i$,然後把當前的 $a_i, a_{i+1}, \ldots, a_n$ 全部同時 $+1$ 或 $-1$。輸出最少的步數。
題解
注意到
- 在解答中任意變換操作順序,仍然不影響加總結果。
- 在最少的步數下,$a_1$ 只有一種方法可以變成 $b_1$,而且必定花費 $\vert b_1-a_1\vert$ 步。
因此由 1. 我們可以只考慮那些按照註標遞增順序的那些操作序列。再由 2. 我們可以依序遞推每一個「當前」的 $a_i$ 需要經過幾的操作,於是就可以得出答案啦。
參考程式碼
// by tmt514
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <string>
#include <vector>
#define SZ(x) ((int)(x).size())
#define FOR(it, c) for(__typeof((c).begin()) it = (c).begin(); it != (c).end(); ++it)
using namespace std;
typedef long long LL;
const int N = 200005;
int a[N], b[N];
int main(void) {
int n;
scanf("%d", &n);
for(int i=0;i<n;i++) scanf("%d", &a[i]);
for(int i=0;i<n;i++) scanf("%d", &b[i]);
long long ans = 0, cur = 0;
for(int i=0;i<n;i++) {
ans += abs(a[i]+cur - b[i]);
cur = b[i]-a[i];
}
cout << ans << endl;
return 0;
}