Educational Round 66
Problem D : Array Splitting
Problem Statement
You are given an array a_1,a_2,…,a_n and an integer k.
You are asked to divide this array into k non-empty consecutive subarrays. Every element in the array should be included in exactly one subarray. Let f(i) be the index of subarray the i-th element belongs to. Subarrays are numbered from left to right and from 1 to k.
Let the cost of division be equal to ∑(a_i⋅f(i)).
For example, if a=[1,−2,−3,4,−5,6,−7] and we divide it into 3 subbarays in the following way: [1,−2,−3],[4,−5],[6,−7], then the cost of division is equal to 1⋅1−2⋅1−3⋅1+4⋅2−5⋅2+6⋅3−7⋅3=−9.
Calculate the maximum cost you can obtain by dividing the array a into k non-empty consecutive subarrays.
You can find link to problem here
Solution
Let us assume that the ending indices of the k segments is know to us. Call them E = [e_1, e_2, e_3, ….e_(k-1),e_k] the last segment always ends in n and hence e_k = n
Let us now calculate our ans
which we can now modify since we have E. Since we need to find sum of segments let us calulate the prefix array p as below
p[0] = a[0]
FOR(i,1,n-1) p[i] = p[i-1] + a[i];
Now we can write our answer as
e_k = n thereofore
We can rewrite this by seperating the positive and negative terms.
If you cancel the terms we can reduce this to
Now we want ans to be as big as possible. Therefore the term which is subtracted needs to be small. Since its from the prefix array we sort the prefix and pick the first k-1 elements. This will ensure that ans is maximum.
int main()
{
ll n, k, ans = 0, pn;
cin>>n>>k;
vector<ll>a(n),pre(n-1); FOR(i,1,n)
cin>>a[i-1]; pre[0] = a[0];
FOR(i,1,n-2)
pre[i] = pre[i-1] + a[i]; pn = pre[n-2] + a[n-1];
sort(all(pre)); FOR(i,0,k-2) {
ans += -1LL*pre[i];
} ans += pn*k;
cout<<ans;
return 0;
}