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 C# (judge verdict: Accepted)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication1
{
    class Program
    {
        static readonly double INF = 1e8;

        static void Main(string[] args)
        {
            StringBuilder sb = new StringBuilder();

            string input;

            while (!string.IsNullOrEmpty(input = Console.ReadLine()))
            {
                string[] temp = input.Split(' ');

                int W = int.Parse(temp[0]);

                List<double> r = new List<double>();

                for (int i = 1; i < temp.Length; i++)
                {
                    r.Add(double.Parse(temp[i]));
                }

                int n = r.Count;

                double[,] dp = new double[1 << n, n];

                for (int i = 0; i < (1 << n); i++)
                {
                    for (int j = 0; j < n; j++)
                    {
                        dp[i, j] = INF;
                    }
                }

                for (int i = 0; i < n; i++)
                {
                    dp[(1 << n) - (1 << i) - 1, i] = r[i];
                }

                for (int i = (1 << n) - 1; i >= 0; i--)
                {
                    for (int j = 0; j < n; j++)
                    {
                        if ((i & (1 << j)) != 0) continue;

                        for (int k = 0; k < n; k++)
                        {
                            double dist = 2 * Math.Sqrt(r[j] * r[k]);

                            dp[i, j] = Math.Min(dp[i, j], dp[i | (1 << j), k] + dist);
                        }
                    }
                }

                double min = INF;

                for (int i = 0; i < n; i++)
                {
                    min = Math.Min(min, dp[0, i] + r[i]);
                }
                sb.AppendLine(min > W ? "NA" : "OK");
            }
            Console.Write(sb);
        }
    }
}