Sunday, 19 April 2020

AtCoder Beginner Contest 163

E : Active Infants

Problem Statement - here

Solution :
To make ourselves clear, we can rearrange them in any order we like. So, it is clear that for every element we have to keep it as far as possible from its current position. But wait, our first priority should be the one who has maximum weight, because it contributes maximum to our happiness. So, we should sort the weights in decreasing order and then what?
Let's say we are at the ith index of our sorted weights, whose initial position is ind and its weight is w. We have already placed our (i-1) elements. These elements are either to the very start or the very end of our array. So, this ith element will either come in front or at back. Let's say we have already placed L elements to left and R elements to right, then L+R = i-1.
so the transitions are now very easy to write:
dp[L+1][R] = max(dp[L+1][R],dp[L][R]  + abs(L+1 - ind)*w)
dp[L][R+1] = max(dp[L][R],dp[L][R+1] + abs(n - R- ind)*w)
We can simply loop till i-1 assuming the current index as the number of elements placed to Left (L) first and calculate the first transition table and then assume it as #elements to the right (R) and calculate the second transition table. 

The Implemented Code:
ll dp[2005][2005] = {}; void solve() { ll n; cin>>n; pll a[n+1]; rep(i,1,n+1) cin >> a[i].F , a[i].S = i; sort(a+1,a+n+1,greater<pll>()); rep(i,1,n+1){ rep(j,0,i){ ll L = j; ll R = i-1-j; dp[L+1][R] = max( dp[L+1][R], dp[L][R] + abs(L+1 - a[i].S)*a[i].F ); R = j; L = i-1-j; dp[L][R+1] = max( dp[L][R+1], dp[L][R] + abs(n - R - a[i].S)*a[i].F ); } } ll ans = 0; rep(i,0,n+1){ ans = max(ans,dp[i][n-i]); } cout << ans << endl; }