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: Wrong Answer)

import java.util.Arrays;
import java.util.Scanner;

public class Main {
    static double[][] dis;
    static double dp[][];
    static int n;
    static int g;

    public static void main(String[] args) throws Exception {
        Scanner sc = new Scanner(System.in);
        while (sc.hasNext()) {
            String tmp[] = sc.nextLine().split(" ");
            int l = Integer.parseInt(tmp[0]);
            int rs[] = new int[tmp.length - 1];
            for (int i = 1; i < tmp.length; i++) {
                rs[i - 1] = Integer.parseInt(tmp[i]);
            }
            n = rs.length;
            dis = new double[n][n];
            dp = new double[1 << n][n];
            for (int i = 0; i < 1 << n; i++) {
                Arrays.fill(dp[i], -1);
            }
            for (int i = 0; i < n; i++) {
                dis[i][i] = 0;
            }
            for (int i = 0; i < n; i++) {
                for (int j = i + 1; j < n; j++) {
                    dis[i][j] = dis[j][i] = 1.0
                            * (rs[i] + rs[j])
                            * Math.cos(Math.asin(1.0 * Math.abs(rs[i] - rs[j])
                                    / (rs[i] + rs[j])));
                }
            }
            boolean flag = false;
            for (int i = 0; i < n; i++) {
                for (int j = i + 1; j < n; j++) {
                    g = j;
                    double dis = tsp(0, i);
                    if (dis + rs[i] + rs[j] <= l) {
                        flag = true;
                        i = n;
                        break;
                    }
                }
            }
            System.out.println(flag ? "OK" : "NA");

        }
    }

    public static double tsp(int S, int v) { // S:既に訪れた頂点、v:現在いる頂点
        if (dp[S][v] >= 0) {
            return dp[S][v];
        }
        if (S == (1 << n) - 1 && v == g) {
            return dp[S][v] = 0;
        }
        double res = Double.POSITIVE_INFINITY;
        for (int u = 0; u < n; u++) {
            if ((S >> u & 1) == 0) {
                res = Math.min(res, tsp(S | 1 << u, u) + dis[v][u]);
            }
        }
        return dp[S][v] = res;
    }
}