Problem:
Problem E: カントリーロード

ある過疎地域での話である．
この地域ではカントリーロードと呼ばれるまっすぐな道に沿って，
家がまばらに建っている．
今までこの地域には電気が通っていなかったのだが，
今回政府からいくつかの発電機が与えられることになった．
発電機は好きなところに設置できるが，
家に電気が供給されるにはどれかの発電機に電線を介してつながっていなければならず，
電線には長さに比例するコストが発生する．
地域で唯一の技術系公務員であるあなたの仕事は，
すべての家に電気が供給されるという条件の下で，
できるだけ電線の長さの総計が短くなるような発電機
および電線の配置を求めることである．
なお，発電機の容量は十分に大きいので，
いくらでも多くの家に電気を供給することができるものとする．

サンプル入力の1番目のデータセットを図2に示す．
この問題に対する最適な配置を与えるには，
図のように x = 20 と x = 80 の位置に発電機を配置し，
それぞれ図中のグレーで示した位置に電線を引けばよい．

図2: 発電機と電線の配置の例（入力例の最初のデータセット）．

Input

入力の1行目にはデータセットの個数 t
(0 < t ≤ 50) が与えられる．

引き続き t 個のデータセットが与えられる．
データセットはそれぞれ次のような形式で2行で与えられる．

n k
x1 x2 ... xn

n は家の戸数，k は発電機の個数である．
x1, x2, ...,
xn
はそれぞれ家の位置を表す一次元座標である．
これらの値はすべて整数であり，
0 < n ≤ 100000,
0 < k ≤ 100000,
0 ≤ x1 < x2 <
... < xn ≤ 1000000
を満たす．

さらに，データセットのうち 90% は，
0 < n ≤ 100, 0 < k ≤ 100 を満たしている．

Output

各データセットに対し，
必要な電線の長さの総計の最小値を1行に出力せよ．

Sample Input

6
5 2
10 30 40 70 100
7 3
3 6 10 17 21 26 28
1 1
100
2 1
0 1000000
3 5
30 70 150
6 4
0 10 20 30 40 50

Output for the Sample Input

60
13
0
1000000
0
20

Solution in JAVA (judge verdict: Memory Limit Exceeded)


import java.util.*;

public class Main {
	
	//private static ArrayList<Integer> xs;
	private static int[] xs;
	
	public static void main(String args[]){
		Scanner scr = new Scanner(System.in);
		int t = Integer.parseInt(scr.nextLine());
		for(int step=0; step<t; step++){
			String[] str = scr.nextLine().split(" ", 0);
			int n = Integer.parseInt(str[0]);
			int k = Integer.parseInt(str[1]);
			//xs = new ArrayList<Integer>();
			xs = new int[n];
			String[] strs = scr.nextLine().split(" ", 0);
			for(int i=0; i<n; i++){
				//xs.add(Integer.parseInt(strs[i]));
				xs[i] = Integer.parseInt(strs[i]);
			}
			if (n==0 && k==0) break; //??\?????????
			Starter(k);
        }
		scr.close();
	}
	private static int[][] memo; // memo[k][start] <- start??\????????????????????§?????????
	private static void Starter(int k){
		if(k>=xs.length)System.out.println(0);
		else{
		memo = new int[k][xs.length/*xs.size()*/];
		for(int i=0; i<k; i++){
			for(int j=0; j<xs.length/*xs.size()*/; j++){
				memo[i][j] = Integer.MAX_VALUE;
			}
		}
		System.out.println( SetDinamo(k, 0) );}
	}
	private static int SetDinamo(int k, int start){ //start??\???????¨????
		if(start>=xs.length/*xs.size()*/){	//NO_HOUSE
			return 0;
		}else if(memo[k-1][start] != Integer.MAX_VALUE){	//?????¢????????????
			return memo[k-1][start];
		}else if(k==1){	//LAST_DINAMO
			memo[k-1][start] = xs[xs.length-1] - xs[start]/*xs.get(xs.size()-1) - xs.get(start)*/;
			return memo[k-1][start];
		}else{
			for(int i=start; i<xs.length/*xs.size()*/; i++){
				int firlen = xs[i]-xs[start]/*xs.get(i) - xs.get(start)*/;
				int reslen = SetDinamo(k-1, i+1);
				memo[k-1][start] = (memo[k-1][start] <= firlen + reslen) ?
						memo[k-1][start] : firlen + reslen;
			}
			return memo[k-1][start];
		}
	}	
	/*private static int SetDinamo(int k, ArrayList<Integer> xs){
		if(xs.size()==0 || k==0) return 0;
		int mlen = Integer.MAX_VALUE;
		//int tlen = Integer.MAX_VALUE;
		int n = xs.size();
		System.out.println(n);
		int a = xs.get(n-1);
		xs.remove(xs.size()-1);
		for(int i=n-2; i>=0; i--){
			System.out.println(k+":"+i);
			int u = xs.get(i);
			xs.remove(i);
			int t = SetDinamo(k-1, xs);
			if(a-u+t<mlen) mlen = a-u+t;
		}
	    return mlen;
	}
	private static int SetDinamo(int k, ArrayList<Integer> xs){
		//System.out.print("Input:" + k + ":" + xs);
		if(xs.size()==0 || k==1){
			if(xs.size()==0){
				//.out.print("No_House ");
				return 0;
			}else{
				//System.out.print("No_Dinamo ");
				return xs.get(xs.size()-1) - xs.get(0);
			}
		}else{
			int minlen = Integer.MAX_VALUE;
			int n = xs.size();
			for(int i=0; i<n; i++){
				int firlen = xs.get(i) - xs.get(0);
				//System.out.print(" fir:" + firlen + " ");
				ArrayList<Integer> xsp = new ArrayList<Integer>();
				for(int j=i+1; j<n; j++){
					xsp.add(xs.get(j));
				}
				int reslen = SetDinamo(k-1, xsp);
				//System.out.print(" res:" + reslen);
				int sumlen = firlen + reslen;
				//System.out.println(" sum:" + sumlen);
				if(minlen > sumlen) minlen = sumlen;
			}
			//System.out.println(" min:" + minlen);
			return minlen;
		}
	}*/
}