AcWing 100. 增减序列(差分,贪心)

题意:给一个数组a,每次可以a的任意区间[l,r]加减1,求最少通过几次操作使得数组a中所有元素大小相等,并输出可能的最小方案次数。
思路:区间加减数,先考虑构造差分数组。
构造差分数组b使得:
a[1]=b[1];
a[2]=b[1]+b[2];
a[3]=b[1]+b[2]+b[3];

要使得最后a中所有元素相等,那么要使得b中b[i](2<=i<=n)都为0,
而了解过差分的性质后可知:对a[l,r]的元素+1等价于差分数组中b[l]+1,b[r]-1。
那么贪心的思路来了,如果要以快的速度达到0,可以选择b[i]<0,b[j]>0,在每次操作中b[i]++,b[j]–,然后最后会只留下一些b[i]全大于0或全小于0,这时可以选择不影响结果的b[1],b[n+1]进行操作,这种就有abs(pos-neg)+1种选法,实质就是在最后只有全大于0或全小于0时,选择b[1]的次数。

int a[N], b[N];
int main()
{
	int n;
	cin >> n;
	f(i, 1, n)scanf("%d", &a[i]);
	f(i, 1, n)b[i] = a[i] - a[i - 1];
	ll pos = 0, neg = 0;
	f(i, 2, n)
	{
		if (b[i] < 0)neg += -b[i];
		else pos += b[i];
	}
	cout << max(pos, neg) << endl;
	cout << abs(pos - neg) + 1 << endl;
	return 0;
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值