Problem:
Score : 500 points

Problem Statement

There are N children standing in a line from left to right. The activeness of the i-th child from the left is A_i.

You can rearrange these children just one time in any order you like.

When a child who originally occupies the x-th position from the left in the line moves to the y-th position from the left, that child earns A_x \times |x-y| happiness points.

Find the maximum total happiness points the children can earn.

Constraints

2 \leq N \leq 2000

1 \leq A_i \leq 10^9

All values in input are integers.

Input

Input is given from Standard Input in the following format:

N
A_1 A_2 ... A_N

Output

Print the maximum total happiness points the children can earn.

Sample Input 1

4
1 3 4 2

Sample Output 1

20

If we move the 1-st child from the left to the 3-rd position from the left, the 2-nd child to the 4-th position, the 3-rd child to the 1-st position, and the 4-th child to the 2-nd position, the children earns 1 \times |1-3|+3 \times |2-4|+4 \times |3-1|+2 \times |4-2|=20 happiness points in total.

Sample Input 2

6
5 5 6 1 1 1

Sample Output 2

58

Sample Input 3

6
8 6 9 1 2 1

Sample Output 3

85

Solution in Rust (1.42.0) (judge verdict: Accepted)

use std::io;

pub trait ExRead {
    fn read_line(&mut self) -> io::Result<String>;
    fn read_to_string(&mut self) -> io::Result<String>;
}

impl ExRead for io::StdinLock<'_> {
    fn read_line(&mut self) -> io::Result<String> {
        let mut buf = String::new();
        io::BufRead::read_line(self, &mut buf).map(|_| buf)
    }

    fn read_to_string(&mut self) -> io::Result<String> {
        self.read_line().map(|s| s.trim().to_string())
    }
}

pub trait SplitAndParse<T: std::str::FromStr> {
    type Result;
    fn split_and_parse(self) -> Self::Result;
}

impl<'a, T: std::str::FromStr> SplitAndParse<T> for &'a str {
    type Result = Result<Vec<T>, <T as std::str::FromStr>::Err>;
    fn split_and_parse(self) -> Self::Result {
        self.split_whitespace()
            .map(|e| e.parse())
            .fold(Ok(Vec::new()),
                |acc, e| acc.and_then(|mut v| e.map(|parsed| {v.push(parsed); v})))
    }
}

extern crate num;

pub fn abs_diff<T: num::Num + Copy + Ord>(n1: T, n2: T) -> T {
    std::cmp::max(n1, n2) - std::cmp::min(n1, n2)
}

fn main() {
    let n: usize;
    let mut a: Vec<(usize, usize)>;

    {
        let stdin = std::io::stdin();
        let mut lkin = stdin.lock();
        let mut input = lkin.read_line().unwrap().split_and_parse().unwrap().into_iter();
        n = input.next().unwrap();
        a = (1..=n).zip(lkin.read_line().unwrap().split_and_parse().unwrap()).collect();
    }

    a.sort_by_key(|&(_, a)| a);
    let mut dp = Vec::new();
    dp.resize(n+1, Vec::new());
    dp.iter_mut().enumerate().for_each(|(i, v)| v.resize(n-i+1, 0));
    for i in 1..=n {
        dp[i][0] = dp[i-1][0] + a[n-i].1 * abs_diff(a[n-i].0, i);
        dp[0][i] = dp[0][i-1] + a[n-i].1 * abs_diff(a[n-i].0, n-i+1);
    }

    for pick in 2..=n {
        for r_align in 1..pick {
            dp[pick - r_align][r_align] = std::cmp::max(
                dp[pick - r_align - 1][r_align] + a[n-pick].1 * abs_diff(a[n-pick].0, pick - r_align),
                dp[pick - r_align][r_align - 1] + a[n-pick].1 * abs_diff(a[n-pick].0, n - r_align + 1)
            );
        }
    }
  
    println!("{}", dp.iter().max_by_key(|v| v.last().unwrap()).unwrap().last().unwrap());
}