#include<iostream> usingnamespace std; constint N = 100010; int n; int b[N];
intmain() { cin >> n; for(int i = 1; i <= n; i ++ ) cin >> b[i]; // 读入x for(int i = 1; i <= n; i ++ ) // 读入y直接 x - y { int x; cin >> x; b[i] -= x; }
for(int i = n + 1; i > 0; i -- ) b[i] -= b[i - 1]; // 求导
// 因为差分数组一定是一加一减, 并且sum(+) + sum(-)一定等于0, 那么操作次数其实就是看正数总和就行 int sum = 0; for(int i = 1; i <= n + 1; i ++ ) if(b[i] > 0) sum += b[i]; cout << sum << endl; return0; }
#include<iostream> #define rep(i, a, b) for(int i = (a); i <= (b); i++ ) #define int long long usingnamespace std; int n, m; int p[200]; // 所有牛栏的降温需求 int b[200]; // 枚举的空调的降温 int a[200]; int ans = 0x3f3f3f3f;
structnode{ int a, b, p, m; // 范围, 降温, 花销 }nodes[20];
// 空调只有10个枚举用不用就行 voidinsert(int l, int r, int c, int b[]) { b[l] += c; b[r + 1] -= c; }
我们的目的是a -> 0, 那么也可以翻转成 0 -> a, 这个过程是通过等差数列区间操作实现的.
那么只要我们把a求导两次, 就可以把这种操作转化成普通的差分操作.
由于本题操作区间一定到最右, 所以右边的边界问题就不用考虑了.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
#include<iostream> #define rep(i, a, b) for(int i = (a); i <= (b); i ++ ) #define int long long usingnamespace std; constint N = 200010; int n; int s[N];
signedmain() { cin >> n; rep(i, 1, n) cin >> s[i]; // s for(int i = n; i >= 1; i -- ) s[i] -= s[i - 1]; // s -> a for(int i = n; i >= 1; i -- ) s[i] -= s[i - 1]; // a -> b int ans = 0; rep(i, 1, n) ans += abs(s[i]); // 正负操作都算 cout << ans << endl; return0; }