Contents
Problem
注意:給 N ,表示 1~N。
Solution
直接舉例:(右邊為步驟數)
1 : 1
1 2 : 2
1 2 3 : 2
可以找出規律
1 2 3 4 => 1 2 1 2
讓右邊成為跟左邊一樣的,所以也就是兩個 1 2,1 則為此次使左右兩邊相同。而 1 2 所要完成的步驟,則是兩個 1。dp[n/2] + 1
可以用遞迴或 DP 去解,但速度較慢。
其中這裡可以發現每次步驟增加都是在 $2^i$ 時,所以我們可以找出 n 是在哪個區間,以求出它的步驟數。
1 => 1
2 => 2
3 => 2
4 => 3
5 => 3
6 => 3
7 => 3
8 => 4
...
以下提供 3 種作法。
Code
建好區間直接查找1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
int main()
{
int dp[30];
int n = 0, i;
for (i = 1; i <= 1000000000; i <<= 1)
dp[n++] = i;
while (scanf("%d", &n) != EOF)
{
for (i = 0; i<30; i++)
if (dp[i] > n)
break;
printf("%d\n", i);
}
return 0;
}
每次都乘以二,找出 n 的所在區間1
2
3
4
5
6
7
8
9
10
11
12
13
14
int main()
{
int n;
while (scanf("%d", &n) != EOF)
{
int ans = 0;
for (int i = 1; i <= n; i <<= 1,ans++);
printf("%d\n", ans);
}
return 0;
}
DP1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
int dp[N + 1];
int main()
{
for (int i = 1; i <= N; i++)
dp[i] = dp[i >> 1] + 1;
int n;
while (scanf("%d", &n) != EOF)
{
if (n <= N)
printf("%d\n", dp[n]);
else if (n <= N << 1)
printf("%d\n", dp[n >> 1] + 1);
else
printf("%d\n", dp[n >> 2] + 2);
}
return 0;
}