bozj - 3043 IncDec Sequence
一.题意
二.输入与输出
三.分析
- 题目中出现 “选择一个区间[ l , r ],使这个区间内的数都+1/-1” 考虑差分原数列简化情况,将对一个区间内的操作转化为对两个数的操作
- 转化后,题目要求变为最少需要多少次操作能够使差分数列中的diff[ 2 ~ n ]都为0
- 这个时候就可以 利用区间修改来使一正一负抵消 ,最后加上剩下未被抵消,只能单独+1/-1的数就是最少操作数
- 所以最少操作数为max(负数和,正数和);
- 以下图一为例,当中间部分的值 > (或者 < ) 首尾两端的值时候,首尾两端需要分别2 * n 次( +1/-1 )才能够达到该值
- 以下图二为例,当中间部分的值在首尾两端的值中间的时候,中间仅需要n次( +1/-1 )就可以达到区间内的值
- 所以方案数为首尾两端的差值+1,即abs( a[1] - a[n] ) + 1;且最终序列也是首尾两端的值,即[ a[1],a[n] ];
图一
图二
四.代码
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
int n,a[100010],diff[100010];
int main(){
cin>>n>>a[1];
ll p,q = 0;
for(int i = 2; i <= n; i++){
cin>>a[i];
diff[i] = a[i] - a[i-1];
if(diff[i] > 0) p += diff[i];
else q += abs(diff[i]);
}
cout<<max(p,q)<<endl;
cout<<abs(a[1] - a[n]) + 1<<endl;
return 0;
}