题目描述
原题链接:4262.空调
解题思路
粗看本题,大概意思就是让我们对 T T T数组进行 ± 1 \pm1 ±1操作,使其变成 P P P数组,并求这些操作所需要的最少操作次数。
但我们可以同时对 T T T数组和 P P P数组进行变换,让其同时减去一个 T T T数组的值。这样上面的操作就等价于求出从 0 0 0数组到 P − T P-T P−T数组所需要的最小操作数。
差分
我们知道,如果要想对一个数组的某个区间进行加减操作,最方便的方法是利用差分。
所谓差分,就是利用原数组构造一个数组,使其满足
a
[
i
]
=
a
[
i
−
1
]
+
b
[
i
]
a[i]=a[i-1]+b[i]
a[i]=a[i−1]+b[i]其中,
a
[
i
]
a[i]
a[i]是原数组,
b
[
i
]
b[i]
b[i]是差分数组。
将上面的式子进行变换可得:
b
[
i
]
=
a
[
i
]
−
a
[
i
−
1
]
b[i]=a[i]-a[i-1]
b[i]=a[i]−a[i−1]。
我们求出 P − T P-T P−T的差分数组,记为 b b b。这样原问题就等价于求出对 b b b数组进行差分操作得到 0 0 0数组所需的最小操作数了。
贪心
我们知道,每当进行一次差分操作,就必有一个差分数组的元素
+
1
+1
+1且必有一个差分数组的元素
−
1
-1
−1。
那么我们一个最简单的直觉就是求出所有正数的和,即为操作的次数。
c++代码
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 100010;
int n, t[N], p[N], a[N];
int main()
{
cin >> n;
for(int i = 1; i <= n; i++) cin >> p[i];
for(int i = 1; i <= n; i++) cin >> t[i];
for(int i = 1; i <= n; i++) p[i] = p[i] - t[i];
int ans = 0;
for(int i = 1; i <= n+1; i++)
{
a[i] = p[i] - p[i-1];
if(a[i] > 0) ans += a[i];
}
cout << ans;
}