코딩 공부 연습
백준 2410 2의 멱수의 합
miffy짱
2023. 2. 24. 20:40
반응형
백준 2410 2의 멱수의 합
dp 문제 2의 멱수의 합을 풀었다. 이렇게 대놓고 dp 인 문제들은 괜찮은데, 이렇게 dp라고 생각하고 풀지 않으면 dp인지 조차 알 수 없는 문제들은 어떻게 해야할까 막막하다.
약간은 무식하게 규칙을 찾고자 써내려가보았다. 그리고 찾은 첫번째 규칙(?) 은 홀수는 생각할 필요가 없다는 것이었다. 홀수일 경우 dp 값은 1작은 짝수의 그것과 같다.
이제 계속 써내려가 보자.
111111 11 11 11 11
11 2 2 11 11 11 11
11 4 11 11 11 11
1111 2 11 11 11 11
2 2 2 11 11 11 11
2 4 11 11 11 11
2 2 2 2 11 11 11
2 2 4 11 11 11
4 4 11 11 11
8 11 11 11
2 2 2 2 2 11 11
2 2 2 4 11 11
2 4 4 11 11
2 8 11 11
2 2 2 2 2 2 11
2 2 2 2 4 11
2 2 4 4 11
4 4 4 11
2 2 8 11
4 8 11
2 2 2 2 2 2 2
2 2 2 2 2 4
2 2 2 4 4
2 4 4 4
2 2 2 8
2 4 8
실제로 이렇게 써내려가면서 확인해 보았는데, 현재 n 이 짝수라면, n-2 에 1 1 이 추가 된 것에 더해, 1을 아예 사용하지 않고 2, 4, 8 .. 등만을 사용하여 나타내는 방법들이 추가되는 걸 확인할 수 있다. 여기까지를 dp로 써보면,
*dp[n] = dp[n-2] + (n을 2멱수만을 이용해 나타낸 경우들) *
이제 저 오른쪽의 경우를 어떻게 계산할 지 고민해보자.
2 2 2 2 2 2 2
2 2 2 2 2 4
2 2 2 4 4
2 4 4 4
2 2 2 8
2 4 8
이 부분을 2로 나누어서 써보자.
1 1 1 1 1 1 1
1 1 1 1 1 2
1 1 1 2 2
1 2 2 2
1 2 4
아까 홀수인 경우 1이 추가 되니 홀수는 1 더 작은 짝수와 dp가 같다고 한걸 생각하면, 저 친구는
1 1 1 1 1 1
1 1 1 1 2
1 1 2 2
2 2 2
2 4
로 나타낼 수 있겠고, 저 친구는 신기하게도 dp[6] 이당 wow
그래서 dp 식을 다음처럼 세울 수 있겠다고 생각했고, 실제로 코드로 굴려보니 바로 통과되었다.
dp[n] = dp[n-2] + dp[n/2]
#include <iostream>
#include <vector>
#include <math.h>
using namespace std;
long long dp[1000002];
int main()
{
long long n;
cin>>n;
dp[1]= 1;
dp[2] = 2;
dp[3] = 2;
dp[4] = 4;
dp[5] = 4;
dp[6] = 6;
dp[7] = 6;
dp[8] = 10;
dp[9] = 10;
dp[10] = 14;
dp[11] = 14;
dp[12] = 20;
dp[13] = 20;
dp[14] = 26;
dp[15] = 26;
for (int i = 16; i <=n; i++)
{
if (i % 2 == 1)
{
dp[i] = dp[i-1];
}
else
{
dp[i] = (dp[i-2] + dp[i/2]) % 1000000000;
}
}
cout<<dp[n];
return 0;
}
(저렇게 dp 많이 할 필요는 전혀 없다. 내가 써보면서 하느라.. 히)
재밌는 문제였다!