The grass has dried up in Farmer John's pasture due to a drought. After hours of despair and contemplation, Farmer John comes up with the brilliant idea of purchasing corn to feed his precious cows.
FJ’s?NN?cows (1≤N≤1051≤N≤105) are arranged in a line such that the?iith cow in line has a hunger level of?hihi?(0≤hi≤1090≤hi≤109). As cows are social animals and insist on eating together, the only way FJ can decrease the hunger levels of his cows is to select two adjacent cows?ii?and?i+1i+1?and feed each of them a bag of corn, causing each of their hunger levels to decrease by one.
FJ wants to feed his cows until all of them have the same non-negative hunger level. Please help FJ determine the minimum number of bags of corn he needs to feed his cows to make this the case, or print??1?1?if it is impossible.
Each input consists of several independent test cases, all of which need to be solved correctly to solve the entire input case. The first line contains?TT?(1≤T≤1001≤T≤100), giving the number of test cases to be solved. The?TT?test cases follow, each described by a pair of lines. The first line of each pair contains?NN, and the second contains?h1,h2,…,hNh1,h2,…,hN. It is guaranteed that the sum of?NN?over all test cases is at most?105105. Values of?NN?might differ in each test case.
Please write?TT?lines of output, one for each test case.
Note that the large size of integers involved in this problem may require the use of 64-bit integer data types (e.g., a "long long" in C/C++).
5 3 8 10 5 6 4 6 4 4 6 4 3 0 1 0 2 1 2 3 10 9 9
14 16 -1 -1 -1
For the first test case, give two bags of corn to both cows?22?and?33, then give five bags of corn to both cows?11?and?22, resulting in each cow having a hunger level of?33.
For the second test case, give two bags to both cows?11?and?22, two bags to both cows?22?and?33, two bags to both cows?44?and?55, and two bags to both cows?55?and?66, resulting in each cow having a hunger level of?22.
For the remaining test cases, it is impossible to make the hunger levels of the cows equal.
Additionally,?NN?is always even in inputs 3-5 and 9-11, and?NN?is always odd in inputs 6-8 and 12-14.
Problem credits: Arpan Banerjee
[/hide]
(Analysis by Arpan Banerjee, Benjamin Qi)
Define an?operation?on?(i,i+1)(i,i+1)?as the act of decreasing both?hihi?and?hi+1hi+1?by one. Also define?ff?to be the final hunger value.
Half Credit:
For inputs 1-8, it suffices to try all possible values of?ff?from?00?to?min(hi)min(hi)?and see if they result in valid solutions. This can be done by sweeping left to right across?hh?and remedying instances where?hihi?is greater than?ff?by doing operations on?(i,i+1)(i,i+1)?until one of?hihi?or?hi+1hi+1?equals?ff. If there is a solution, this method must lead to it, because doing operations on?(i,i+1)(i,i+1)?is the only way to make?hihi?equal?ff?assuming no more operations on?(i?1,i)(i?1,i)?are allowed.
This solution runs in?O(Nmax(hi))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?ii?such that?hi?1<hihi?1<hi. If?i=Ni=N, then there is no solution because no operation can bring?hNhN?closer to?hN?1hN?1. Otherwise, the only way to make?hihi?equal to?hi?1hi?1?is to do at least?hi?hi?1hi?hi?1?operations on?(i,i+1)(i,i+1). Similar reasoning applies when?hi?1>hihi?1>hi?(there is no solution if?i=2i=2, otherwise at least?hi?1?hihi?1?hi?operations must be performed on?(i?2,i?1)(i?2,i?1)).
One approach is to repeatedly find the leftmost pair?(i?1,i)(i?1,i)?such that?hi?1≠hihi?1≠hi?and perform the appropriate number of operations to make?hi?1=hihi?1=hi. It can be proven that this terminates in?O(N3)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?hh?and applying the necessary number of operations to?(i,i+1)(i,i+1)?to make?hihi?equal to?hi?1hi?1?whenever we find?ii?such that?hi>hi?1hi>hi?1. After doing a pass through the array with this procedure, either?hN>hN?1hN>hN?1?(in which case there is no solution), or?hh?will be non-increasing (hi≤hi?1hi≤hi?1?for all?2≤i≤N2≤i≤N).
In the latter case, let's reverse?hh. Now?hh?will be non-decreasing (hi≥hi?1hi≥hi?1?for all?2≤i≤N2≤i≤N). After one more pass with the above procedure, all elements of?hh?will be equal except possibly?hNhN. If?hN>hN?1hN>hN?1, then there is no solution. Otherwise, all elements of?hh?are equal, and it remains to verify whether these elements are non-negative.
This solution takes?O(N)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?oioi?be the total number of operations FJ performs on?(i,i+1)(i,i+1)?for each?1≤i<N1≤i<N. The goal is to find the maximum?ff?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:
Also,
The first solution in the analysis can be interpreted as trying all possible values of?ff?from?00?to?min(hi)min(hi), determining?o1,o2,…,oN?1o1,o2,…,oN?1?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.
Observe that if?NN?is odd, the last equation uniquely determines?ff, so we can simply plug this value of?ff?into the brute force solution.
If?NN?is even, then if there exists some?ff?such that this system of equations, then?f′=0f′=0?will as well. Let?o′1,o′2,…,o′N?1o1′,o2′,…,oN?1′?be the resulting numbers of operations. To find the maximum?ff, observe from the above equations that increasing?f′f′?will decrease?o′1,o′3,…,o′N?1o1′,o3′,…,oN?1′, while?o′2,o′4,…,o′N?2o2′,o4′,…,oN?2′?remain constant. Thus, we may take?f=min(o′1,o′3,…,o′N?1)f=min(o1′,o3′,…,oN?1′).
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"; } }
[/hide]
? 2025. All Rights Reserved. 沪ICP备2023009024号-1