금고 ¶
, 고, 간 까 고 . n, 금고 k , O(nk). 구간 값 간 .
¶
T(n, k) n 과 금고 k . 기 n k 개 금고 고, T(n, k) .
n 금고 고 . 그 그 , T(b, k) 고, T(a, k-1) . 기 a, b 금고 기 . 기 구고
{{| max{ T(b, k), T(a, k-1) } + 1 |}} .
그 기 T(b,k) > T(a, k-1) 거 T(b,k) < T(a,k-1) 이라면 n = a + b + 1 인 건물의 층수가 우리가 처음에 가정한 n이 T(n,k) 횟수만에 테스트 할 수 있는 건물의 최대 높이라는 가정과 모순된다. 따라서 T(b,k) = T(a,k-1) 이다. 따라서
{{| T(a+b+1, k) = T(b,k) + 1 = T(a,k-1) + 1 |}} . 기 a b . 기값 T(1, k) = 1, T(n, 1) = n 값 구 .
n 금고 고 . 그 그 , T(b, k) 고, T(a, k-1) . 기 a, b 금고 기 . 기 구고
{{| max{ T(b, k), T(a, k-1) } + 1 |}} .
그 기 T(b,k) > T(a, k-1) 거 T(b,k) < T(a,k-1) 이라면 n = a + b + 1 인 건물의 층수가 우리가 처음에 가정한 n이 T(n,k) 횟수만에 테스트 할 수 있는 건물의 최대 높이라는 가정과 모순된다. 따라서 T(b,k) = T(a,k-1) 이다. 따라서
{{| T(a+b+1, k) = T(b,k) + 1 = T(a,k-1) + 1 |}} . 기 a b . 기값 T(1, k) = 1, T(n, 1) = n 값 구 .
¶
~cpp
// Safe
#include <iostream>
using namespace std;
#define MAXN 500
static int d[MAXN+1][MAXN+1];
static int n, k;
void init_table()
{
for (int i = 1; i <= MAXN; i++)
{
d[1][i] = 1;
d[i][1] = i;
}
}
int find_max_n(int k, int value)
{
for (int i = 1; i <= MAXN; i++)
if (value < d[i][k])
return i - 1;
return -1;
}
void fill_cell(int k)
{
int a, b, t, value;
t = value = 1;
while (t < MAXN)
{
b = t;
a = find_max_n(k - 1, value);
t = a + b + 1;
for (int i = b + 1; i <= __min(t,MAXN); i++)
d[i][k] = value + 1;
value++;
}
}
void set_dynamic_table()
{
init_table();
for (int k = 2; k <= MAXN; k++)
fill_cell(k);
}
inline void show()
{
cout << d[n][k] << endl;
}
int main()
{
int nCase;
cin >> nCase;
set_dynamic_table();
for (int i = 0; i < nCase; i++)
{
cin >> n >> k;
show();
}
return 0;
}










