Processing math: 100%
(Analysis by Arpan Banerjee, Benjamin Qi)

Define an operation on (i,i+1) as the act of decreasing both hi and hi+1 by one. Also define f to be the final hunger value.

Half Credit:

For inputs 1-8, it suffices to try all possible values of f from 0 to min(hi) and see if they result in valid solutions. This can be done by sweeping left to right across h and remedying instances where hi is greater than f by doing operations on (i,i+1) until one of hi or hi+1 equals f. If there is a solution, this method must lead to it, because doing operations on (i,i+1) is the only way to make hi equal f assuming no more operations on (i1,i) are allowed.

This solution runs in O(Nmax(hi)) time.

Arpan's code:

#include<bits/stdc++.h>
#define int long long
#define nl "\n"
using namespace std;

int n;
const int inf = 1e18;

int cost(vector<int> h, int f){
	int o = 0;
	for (int i = 0; i < n - 1; i++){
		if (h[i] > f){
			int sub = min(h[i], h[i + 1]) - f;
			h[i] -= sub, h[i + 1] -= sub;
			o += sub * 2;
		}
	}
	for (int i = 0; i < n - 1; i++)
		if (h[i] != h[i + 1])
			return inf;
	return o;
}

int exe(){
	cin >> n; vector<int> h(n);
	int mn = inf, ans = inf;
	for (int& i : h) cin >> i, mn = min(mn, i);
	for (int f = 0; f <= mn; f++)
		ans = min(ans, cost(h, f));
	return (ans == inf ? -1 : ans);
}

signed main(){
	cin.tie(0)->sync_with_stdio(0); cin.exceptions(ios_base::failbit);
	int t; cin >> t;
	while (t--) cout << exe() << nl;
}

(Almost) Full Solution:

Consider any i such that hi1<hi. If i=N, then there is no solution because no operation can bring hN closer to hN1. Otherwise, the only way to make hi equal to hi1 is to do at least hihi1 operations on (i,i+1). Similar reasoning applies when hi1>hi (there is no solution if i=2, otherwise at least hi1hi operations must be performed on (i2,i1)).

One approach is to repeatedly find the leftmost pair (i1,i) such that hi1hi and perform the appropriate number of operations to make hi1=hi. It can be proven that this terminates in O(N3) time, and is enough to solve all but the last input.

Ben's code:

#include <bits/stdc++.h>
using namespace std;
 
using i64 = int64_t;
 
i64 solve(vector<i64> h){
	const int N = (int)h.size();
	i64 ans = 0;
	auto operations = [&h,&ans](int idx, i64 num_op) {
		assert(num_op >= 0);
		h.at(idx) -= num_op; 
		h.at(idx+1) -= num_op;
		ans += 2*num_op;
	};
	bool flag = true;
	while (flag) {
		flag = false;
		for (int i = 1; i < N; ++i) if (h[i-1] != h[i]) {
			flag = true;
			if (h[i-1] < h[i]) {
				if (i == N-1) return -1;
				operations(i,h[i]-h[i-1]);
			} else {
				if (i == 1) return -1;
				operations(i-2,h[i-1]-h[i]);
			}
			break;
		}
	}
	// now h is all equal
	if (h[0] < 0) return -1;
	return ans;
}

int main() {
	int t; cin >> t;
	while (t--) {
		int N; cin >> N;
		vector<i64> H(N);
		for (auto& i: H) cin >> i;
		cout << solve(H) << "\n";
	}
}

Full Solution 1:

For a faster solution, let's start by moving left to right across h and applying the necessary number of operations to (i,i+1) to make hi equal to hi1 whenever we find i such that hi>hi1. After doing a pass through the array with this procedure, either hN>hN1 (in which case there is no solution), or h will be non-increasing (hihi1 for all 2iN).

In the latter case, let's reverse h. Now h will be non-decreasing (hihi1 for all 2iN). After one more pass with the above procedure, all elements of h will be equal except possibly hN. If hN>hN1, then there is no solution. Otherwise, all elements of h are equal, and it remains to verify whether these elements are non-negative.

This solution takes O(N) time.

Arpan's code:

#include<bits/stdc++.h>
#define int long long
#define nl "\n"
using namespace std;

int exe(){
	int ans = 0, n;
	cin >> n; vector<int> h(n);
	for (int& i : h) cin >> i;
	if (n == 1) return 0;
	for (int j : {1, 2}){
		for (int i = 1; i < n - 1; i++){
			if (h[i] > h[i - 1]){
				int dif = h[i] - h[i - 1];
				ans += 2 * dif, h[i + 1] -= dif, h[i] = h[i - 1];
			}
		}
		if (h[n - 1] > h[n - 2]) return -1;
		// now h is non-increasing
		reverse(h.begin(), h.end());
		// now h is non-decreasing
	}
	// now h is all equal
	return h[0] < 0 ? -1 : ans;
}

signed main(){
	cin.tie(0)->sync_with_stdio(0); cin.exceptions(ios_base::failbit);
	int t; cin >> t;
	while (t--) cout << exe() << nl;
}

Full Solution 2:

Let oi be the total number of operations FJ performs on (i,i+1) for each 1i<N. The goal is to find the maximum f such that there exists a solution to the following system of equations. Firstly, the final hunger value and the number of operations performed at every pair of indices must be non-negative:

f,o1,,oN10

Also,

f+o1=h1
f+o1+o2=h2
f+o2+o3=h3
f+oN2+oN1=hN1
f+oN1=hN

The first solution in the analysis can be interpreted as trying all possible values of f from 0 to min(hi), determining o1,o2,,oN1 in that order, and checking whether all of them are non-negative. For a faster solution, let’s rewrite the system of equations in the following form.

o1=h1f0
o2=h2h10
o3=h3h2+h1f0
oN1=hN1hN2+hN30
hNhN1+hN2hN3+...+h2h1=0 if N even
hNhN1+hN2hN3+...h2+h1f=0 if N odd

Observe that if N is odd, the last equation uniquely determines f, so we can simply plug this value of f into the brute force solution.

If N is even, then if there exists some f such that this system of equations, then fâ=0 will as well. Let o1â,o2â,,oN1â be the resulting numbers of operations. To find the maximum f, observe from the above equations that increasing fâ will decrease o1â,o3â,,oN1â, while o2â,o4â,,oN2â remain constant. Thus, we may take f=min(o1â,o3â,,oN1â).

Ben's code:

#include <bits/stdc++.h>
using namespace std;
 
using i64 = int64_t;
 
i64 solve(const vector<i64>& H) {
	const int N = (int)H.size();
	i64 f = 0;
	for (int i = 0; i < N; ++i)
		f += (i%2 == 0 ? 1 : -1)*H[i];
	if (N%2 == 0) {
		if (f != 0) return -1;
	} else {
		if (f < 0) return -1;
	}
	i64 last_o = 0;
	vector<i64> o(N-1);
	for (int i = 0; i+1 < N; ++i) {
		last_o = o[i] = H[i]-f-last_o;
		if (o[i] < 0) return -1;
	}
	if (N%2 == 0) {
		i64 mn = o[0];
		for (int i = 0; i < N; i += 2)
			mn = min(mn,o[i]);
		for (int i = 0; i < N; i += 2)
			o[i] -= mn;
	}
	i64 sum_o = 0;
	for (i64 i: o) sum_o += i;
	return 2*sum_o;
}
 
int main() {
	int t; cin >> t;
	while (t--) {
		int N; cin >> N;
		vector<i64> H(N);
		for (auto& i: H) cin >> i;
		cout << solve(H) << "\n";
	}
}