IncDec Sequence(差分)

题意:有操作为选择[i,j]区域,使得区域内的数+1或者-1,求:1.至少需要多少操作使得数列中的数都一样。2.保证最少次数前提下最终可得数列可能有多少组。

设b数组为数列a的差分,b[1] = a[1],b[2] = a[2] - a[1],…,b[n] = a[n]-a[n-1]。再设b[n+1] = 0;

解析题意:利用差分的思想,在[i,j]中同时全部+1可以转化为b[i]+1且b[j+1]-1。
所以转化题意为:在b数列中,每次可以选出b[1]…b[n+1]中的任意两个数,一个+1,一个-1,最终使得b[2]…b[n]的数都为零,最终的a数列就是n个b[1]构成的。

但是要考虑几种情况

  1. b[2]…b[n]中有正负数同在的时候,每次选择b[2]…b[n]中的数+1,-1
  2. 选b[1]和b[n]
  3. 选b[2]…b[n]和b[n+1]
  4. ~~选b[1]和b[n+1]~~对b[2]…b[n]中无变化

分析:假如有q个正数,p个负数,则1执行了min(p,q)次,接下来还要执行2或3,每个两个都是每次执行一次,所以总共最少次数是min(p,q)+|p-q|=max(p,q)。当把正负抵消了之后,每一次操作都可以执行2操作,在加上本身自己的一个,所以总共有|p-q|+1组。

#include<iostream>
#include<cstring>
#include<cmath>
using namespace std;
int main()
{
	const int N = 10005;
	int n,a[N],b[N];
	cin>>n;
	for(int i=1;i<=n;i++){
		cin>>a[i];
		if(i==1) b[i] = a[i];
		else b[i] = a[i]-a[i-1];
	} 
	int pos=0,neg=0;
	for(int i=1;i<=n;i++){
		if(b[i]<0) neg++;
		if(b[i]>0) pos++;
	} 
	
	cout<<max(pos,neg)<<endl<<abs(pos-neg)+1; 
	
	return 0;
}
发布了6 篇原创文章 · 获赞 6 · 访问量 162

猜你喜欢

转载自blog.csdn.net/weixin_43626741/article/details/104361228