题目描述:
思路:
此题非常有技巧,我们首先可以先把希望温度和实际温度做差,
问题就转化成,把这个温度差如何去全都变为0,相对应的变成希望温度
也就是 去给温度差数组去做差分,因为(它将一组连续的牛栏内的温度升高或降低 1
个单位)这句话,
1、 所以我们可以把区间去加减1(等价于对 a[l,r]内所有元素加一或减一,
l=r就是对一个元素操作,此处 r<n)
2、 也可也只减或者只加某个区间(等价于对 a[l,n]内所有元素加一或减一,l=n
就是对最后一个元素操作)
然后通过此例子 希望温度和实际温度 做差后 数组是 0 3 1 1 3
差分后是0 3 -2 0 2 把其差分数组全都变为0 等价于去把温度差全部弥补上
也就是相当于原数组是0 0 0 0 0
我们每次可以从 b(温度差的差分数组)中同时挑一个正数减 1,和一个负数加 1
也可以只挑一个正数减 1,或一个负数加 1
所以最少次数是 b 中所有正数的和,和所有负数和的绝对值的较大者。即如果 b
中还有一对正负数就一起操作,否则只能逐个操作,(差分的性质)
AC代码:
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cmath>using namespace std;const int N = 1e5+10;
int a[N],b[N];void insert(int l,int r,int c)
{b[l] += c;b[r+1] -= c;
}int main()
{cin.tie(0)->ios::sync_with_stdio(false);int n;cin >> n;//希望温度数组for(int i=1;i<=n;i++) cin >> a[i];//求出p与t温差for(int i=1;i<=n;i++){int t;cin >> t; //实际温度a[i] = a[i] - t;}//求出温差的差分for(int i=1;i<=n;i++){insert(i,i,a[i]);}int res1=0,res2=0;for(int i=1;i<=n;i++){if(b[i] > 0) res1 += b[i];else res2 -= b[i];}cout << max(res1,res2);return 0;
}