AcWing 100. IncDec序列(差分)

题目链接:点击这里

在这里插入图片描述
在这里插入图片描述

本题要求将数组元素化为相同的元素,相当于对差分数组 b [ 2 ] b [ n ] b[2] \sim b[n] 都置为 0 0

对差分数组 b [   ] b[\ ] 可以进行下面四种操作:

(1) 2 < = i , j < = n 2<=i,j<=n
(2) i = 1 2 < = j < = n i=1,2<=j<=n
(3) 2 < = i < = n j = n + 1 2<=i<=n,j=n+1
(4) i = 1 j = n + 1 i=1,j=n+1

要求操作数最少,根据贪心思想,优先选择第一种操作,即进行 m i n ( p o s , n e g ) min(pos, neg) 次操作。

第一种结束后,正数和 p o s pos 与负数和 n e g neg 绝对值之差可能不为 0 0 ,我们接着选择第二或第三种操作都可以,又进行 a b s ( p o s n e g ) abs(pos-neg) 次操作。

再来考虑最终得到的数列可能有多少种。

我们选第二种操作的次数是 0 ,   1 ,   2 ,   ,   a b s ( p o s n e g ) 0,\ 1,\ 2,\ …,\ abs(pos-neg) ,对应选第三种操作的次数是 a b s ( p o s n e g ) ,   a b s ( p o s n e g ) 1 ,   ,   0 abs(pos-neg),\ abs(pos-neg)-1,\ …,\ 0 ,一共 a b s ( p o s n e g ) + 1 abs(pos-neg)+1 种选择,对应着 a b s ( p o s n e g ) + 1 abs(pos-neg)+1 种不同结果。

#include<iostream>
#include<algorithm>
#include<string>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<stack>
#include<queue>
#include<map>
#include<set>

using namespace std;
typedef long long ll;
const int MOD = 10000007;
const int INF = 0x3f3f3f3f;
const double PI = acos(-1.0);
const int maxn = 100010;
int a[maxn];

int main()
{
	int n;
	scanf("%d", &n);
	for(int i = 1; i <= n; ++i)
		scanf("%d", &a[i]);
	
	for(int i = n; i > 1; --i)
		a[i] -= a[i-1];		//求差分,这里必须逆序
	
	ll pos = 0, neg = 0;
	for(int i = 2; i <= n; ++i)
	{
		if(a[i]>0)	pos += a[i];
		else	neg -= a[i];
	}
	
	printf("%lld\n", min(pos,neg) + abs(pos-neg));
	printf("%lld\n", abs(pos-neg) + 1);
	return 0;
}
发布了727 篇原创文章 · 获赞 111 · 访问量 12万+

猜你喜欢

转载自blog.csdn.net/qq_42815188/article/details/104260083