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 C (Clang 10.0.0) (judge verdict: Runtime Error)

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int **dmatrix(int x,int y);	//x行y列の配列を確保する.
void free_dmatrix(int **a,int x);//x行の配列を解放する
 
int main(void){
	int N,*A,max_score;
	int *max_num;//数字Anの大きい順に配列の場所が収納される
	int **DP,x,y;    //DP[x][y]は右に移動がx左に移動がy個での最大スコア
	int i,j,k;
	char str[10000];
 
	fgets(str, sizeof(str), stdin);
	N=atoi(strtok(str," "));
	
	A = (int*)calloc(N,sizeof(int));
	max_num = (int*)calloc(N,sizeof(int));
	DP=dmatrix(N+1,N+1);//x,yの範囲は0～N
	
	/*順番などを収納*/
	fgets(str, sizeof(str), stdin);	
	A[0]=atoi(strtok(str," "));
	for(i=1;i<N;i++){		//大きい順にmax_numに値が入ってない要修正
		A[i]=atoi(strtok(NULL," "));
		for(j=0;j<i;j++){
			 if(A[max_num[j]] < A[i]) break; 
		}
		for(k=i;k>j;k--){
			max_num[k]=max_num[k-1];
		}
		max_num[j]=i;
	}
	/*順番などを収納*/

	/*マップの作成*/
	DP[1][0]=A[max_num[0]]*abs(N-1-max_num[0]);	//最大値を一番右へ
	DP[0][1]=A[max_num[0]]*abs(max_num[0]-0);	//最大値を一番左へ
	for(i=2;i<=N;i++){//移動させる個数i=x+y
		for(x=1;x<=i;x++){//右へ移動
			y=i-x;
			DP[x][y]=DP[x-1][y]+A[max_num[i-1]]*abs( (N-x)-max_num[i-1]);
		}
		for(y=1;y<=i;y++){//左へ移動
			int buff;
			x=i-y;
			buff=DP[x][y-1]+A[max_num[i-1]]*abs( max_num[i-1] - y+1);
			if(buff > DP[x][y])  DP[x][y] = buff;
		}
	}
	/*マップの作成*/

	/*最大スコアの計算*/
	max_score=0;
	for(i=0;i<=N;i++){
		x=i;y=N-x;
		if(DP[x][y] > max_score) max_score=DP[x][y];
	}
	printf("%d\n",max_score);
	/*最大スコアの計算*/

	free(A);
	free(max_num);
	free_dmatrix(DP,N);

	return 0;
}

int **dmatrix(int x,int y)			//x行y列の配列を確保する.
{
	int i;
	int **a;
	if ( ( a = (int**)calloc(x,sizeof(int*)) ) == NULL){
		//printf("メモリの確保に失敗しました.\nプログラムを終了します.");
		exit(1);
	}
	for(i=0;i<x;i++) a[i]=(int*)calloc(y,sizeof(int));
	return (a);
}

void free_dmatrix(int **a,int x)//x行の配列を解放する.
{
	int i;
	for (i=0;i<x;i++) free((void*)(a[i]));	
	free((void*)(a)); 
}