CF 1700C Helping the Nature

题目链接

https://codeforces.com/problemset/problem/1700/C

题目描述

给出一个长度为 n n n 的序列 a a a,每次可以进行三种操作中的一种:

  • 选择 i i i,将 a 1 , a 2 , ⋯   , a i a_1,a_2,\cdots,a_i a1,a2,,ai 1 1 1
  • 选择 i i i,将 a i , a i + 1 , ⋯   , a n a_i,a_{i+1},\cdots,a_n ai,ai+1,,an 1 1 1
  • 将所有 a i a_i ai 1 1 1

求最少需要多少次操作将所有 a i a_i ai 变为 0 0 0

1 ≤ T ≤ 2 × 1 0 4 1\leq T\leq 2\times 10^4 1T2×104 1 ≤ n ≤ 2 × 1 0 5 1\leq n\leq 2\times 10^5 1n2×105 − 1 0 9 ≤ a i ≤ 1 0 9 -10^9\leq a_i\leq 10^9 109ai109 ∑ n ≤ 2 × 1 0 5 \sum n\leq 2\times 10^5 n2×105

输入输出样例

输入样例

4
3
-2 -2 -2
3
10 4 7
4
4 -4 4 -4
5
1 -2 3 -4 5

输出样例

2
13
36
33

解题思路

根据题目中的限制条件可知,作减法运算时对两端的区间起效果,加法运算是对所有数起效果的,我们可以使用操作1或操作2把序列变为单调序列,变为单调序列后再累加就方便多了。
算法步骤:

  1. 使用减法构造一个单调递增的数列;
  2. 将单调递增序列变为正数序列,以 a 1 a_1 a1的值为准;如果 a 1 a_1 a1的值为正,序列不需要累加
  3. 将正数序列变为0序列,操作次数以 a n a_n an为准。

操作次数 = 减的次数+将序列变为正数序列次数+将正数序列变为0的次数

以数据4 -4 4 -4为例:
在这里插入图片描述
做题过程中,根据样例给出的数据模拟一下,很快就可以发现规律了。

参考代码

#include <iostream>
#include <cstdio>
using namespace std;
const int MAXN=200005;
int a[MAXN];
int main(){
	int t;
	//freopen("1700c.txt","r",stdin);
	scanf("%d",&t);
	while ( t-- ) {
		int n;
		scanf("%d",&n);
		for(int i = 1; i <= n; i++){
			scanf("%d", &a[i]);
		}
		long long sum = 0; //累积减掉的数值 
		for(int i = n; i >= 2;i--)
			if( a[i-1] > a[i]) sum += a[i-1] - a[i];
		//printf("%d\n",sum); 
		if( a[1]-sum>=0 ) printf("%lld\n", sum + a[n]);
		else printf("%lld\n",sum+(-1)*(a[1]-sum)*2 + a[n]);
	}
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值