1. 程式人生 > 其它 >CF 1700C Helping the Nature(差分)

CF 1700C Helping the Nature(差分)

題目分析

(妹有思路啊)

本題思路的關鍵是先讓序列的的每一項通過加減統一成一個數,再通過加或減變為0

進一步我們可以想到構造一個差分陣列,從第二項開始通過加減使差分陣列每一項都變為0,每加或減一都要記一次操作,一直操作到最後,此時我們得到了將序列每一項統一成同一數所需的步驟數

那麼接著如何讓原序列的每一項都變為0?假如我們之前將原序列每一項都統一變為了x,此時只需要對所有數同加或同減|x|次一,兩次的步驟數加起來,我們就得到了總的步驟數

參考程式碼

(思路理解了後就會發現其實不用專門構造一個差分陣列)

#include <bits/stdc++.h>
using namespace std;
const int N = 2e5 + 10;
int a[N], s[N];
int main()
{
	int t;
	cin >> t;
	while (t -- )
	{
		memset(s, 0, sizeof s);	// 初始化差分陣列
		int n;
		cin >> n;
		for (int i = 1; i <= n; i ++ )
		{
			cin >> a[i];
			// 構造差分陣列
			// 其實如果這一步通過s[i] = a[i] - a[i -1]的話
			// 前面就不用memset()了
			s[i] += a[i];
			s[i + 1] -= a[i];
		}
		// i項之前每一項都為prev
		long long prev = a[1], ans = 0;
		for (int i = 2; i <= n; i ++ )
		{
			ans += abs(s[i]);	// abs(s[i])為將差分變為0的步驟數
			if (s[i] < 0) prev += s[i];	// 如果s[i] < 0,就要操作i項之前的所有數
		}
		ans += abs(prev);	// abs(prev)為將每一項變為0所需步驟數
		cout << ans << endl;
	}
	return 0;
}