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)

// AOJ 0120: Patisserie
// 2017.8.21 bal4u@uu
// 201711.20

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

int r[13];
double d[13][13];					// ???????????±???????????????????°´????????¢
double dp[13][4100];				// ?°´????????¢, ??´?????????????????±??????????±\??´?????????
char buf[50], *p;

int getint()
{
	int n = 0;
	while (*p >= '0') n = (n<<3) + (n<<1) + (*p++ & 0xf);
	return n;
}

int main()
{
	int w, n, i, ii, j, k;
	int lim;
	double x;

	for (i = 3; i <= 10; i++) for (ii = i*i, j = i; j <= 10; j++, ii+=i)
		d[i][j] = d[j][i] = 2 * sqrt(ii);

	while (fgets(p=buf, 50, stdin) != NULL) {
		w = getint(); p++;
		n = 0, j = 0;
		while (*p >= ' ') {	i = getint(), p++, r[n++] = i, j += i; }
		if (2 * j <= w) { puts("OK"); continue; }

		memset(dp, 0x55, sizeof(dp));
		for (i = 0; i < n; i++)	dp[i][1<<i] = r[i];

		lim = (1 << n) - 1;
		for (k = 0; k <= lim; k++) {
			for (ii = 1, i = 0; i < n; i++, ii <<= 1) {
				if (k & ii) continue;
				for (j = 0; j < n; j++) {
					if (dp[j][k] > 256) continue;
					x = dp[j][k] + d[r[i]][r[j]];
					if (x < dp[i][k|ii]) dp[i][k|ii] = x;
				}
			}
		}

		for (x = 1000, i = 0; i < n; i++) {
			if (dp[i][lim] == 0) continue;
			dp[i][lim] += r[i];
			if (dp[i][lim] < x) x = dp[i][lim];
		}
		puts(x <= w ? "OK" : "NA");
	}
	return 0;
}