Problem:
パティシエ

ケーキ屋さんが、まちまちな大きさのロールケーキをたくさん作りました。あなたは、このケーキを箱に並べる仕事を任されました。

ロールケーキはとてもやわらかいので、他のロールケーキが上に乗るとつぶれてしまいます。ですから、図(a) のように全てのロールケーキは必ず箱の底面に接しているように並べなければなりません。並べ替えると必要な幅も変わります。

図(a)

図(b)

n 個のロールケーキの半径 r1, r2, ..., rn と箱の長さを読み込み、それぞれについて、箱の中にうまく収まるかどうか判定し、並べる順番を工夫すると箱に入る場合は "OK"、どう並べても入らない場合には "NA"を出力するプログラムを作成してください。

ロールケーキの断面は円であり、箱の壁の高さは十分に高いものとします。 ただし、ロールケーキの半径は 3 以上 10 以下の整数とします。つまり、ケーキの半径に極端な差はなく、図(b) のように大きなケーキの間に小さなケーキがはまり込んでしまうことはありません。

Input

入力は複数のデータセットからなります。各データセットは以下の形式で与えられます。

W r1 r2 ... rn

最初に箱の長さを表す整数 W (1 ≤ W ≤ 1,000) が与えられます。 続いて、空白区切りで各ロールケーキの半径を表す整数 ri (3 ≤ ri ≤ 10) が与えられます。ケーキの個数 n は 12 以下です。

データセットの数は 50 を超えません。

Output

データセットごとに OK または NA を１行に出力してください。

Sample Input

30 4 5 6
30 5 5 5
50 3 3 3 10 10
49 3 3 3 10 10

Output for the Sample Input

OK
OK
OK
NA

Solution in JAVA (judge verdict: Accepted)

import java.util.*;
public class Main {
	static final Scanner stdin = new Scanner(System.in);
	static final double INF = 1e8;
	public static void main(String[] args) {
		while(stdin.hasNext()){
			String[] line = stdin.nextLine().split(" ");
			int l = Integer.parseInt(line[0]), n = line.length;
			int[] r = new int[n];
			r[0] = 0;
			for(int i = 1; i < n; ++i) r[i] = Integer.parseInt(line[i]);
			double[][] d = new double[n][n];
			for(int i = 0; i < n; ++i)
				for(int j = 0; j < n; ++j)
					d[i][j] = (i == j ) ? 0 : 
						(i == 0) ? r[j] : 
						(j == 0) ? r[i] : 
						Math.sqrt(Math.pow(r[i] + r[j], 2) - Math.pow(r[i] - r[j], 2));
			System.out.println(TSP(d,0).getLength() <= l ? "OK" : "NA");
		}
	}
	@SuppressWarnings("unused") public static class TSPResult{
		private int s;		//source node (???= destination node)
		private double length;	//length of shortest Hamilton cycle
		private int[][] prev;	//back pointers
		public TSPResult(int s, double length, int[][] prev){ set(s, length, prev); }
		final private void set(int s, double length, int[][] prev){ this.s = s; this.length = length; this.prev = prev; }
		final public double getLength(){ return length; }
	}
	static TSPResult TSP(double[][] G, int s){
		int n = G.length, N = 1 << n;
		double[][] DP = new double[N][n];
		int[][] prev = new int[N][n];
		for(int i = 0; i < N; ++i) Arrays.fill(DP[i], INF);
		for(int i = 0; i < n; ++i){
			DP[1<<i][i] = G[s][i];
			prev[1<<i][i] = s;
		}
		for (int S = 1; S < N; ++S) {
			for (int i = 0; i < n; ++i) {
				if ((S & (1<<i)) == 0) continue;
				for (int j = 0; j < n; ++j) {
					if ((S & (1<<j)) != 0 ) continue;
					//i in S, j not in S 
					double newDist = DP[S][i]+G[i][j];
					if(DP[S|(1<<j)][j] > newDist) {
						DP[S|(1<<j)][j] = newDist;
						prev[S|(1<<j)][j] = i;
					}
				}
			}
		} 
		return new TSPResult(s, DP[N-1][s], prev);
	}
}