problem solving

백준 1955: 수식 표현

finding wangdo 2023. 2. 20. 19:26

https://www.acmicpc.net/problem/1955

 

1955번: 수식 표현

수식 표현이란 1, +, *, !, (, )로만 이루어진 수식을 말한다. 간명하게 정의하기 위해, 다음과 같이 귀납적으로 정의할 수 있다. 1은 수식표현이다. e가 수식표현이면 (e)와 e!도 수식표현이다. e1과 e2

www.acmicpc.net


시간복잡도: n이 10000 이하이기 때문에 O(n^2) 안에 풀 수 있어야 한다.

PART 0.

입력이 i일때 출력해야할 값을 dp[i]라고 두면
일단 dp[0]~dp[8] 값을 생각해보자면
dp[0] = 0;
dp[1] = 1;
dp[2] = 2;
dp[3] = 3;
dp[4] = 4;
dp[5] = 5;
dp[6] = 3;
dp[7] = 4;
dp[8] = 5;

PART 1.

dp[i]에서 i가 어떤 자연수 k에 대해 k!일 때(i는 10000 이하이기 떄문에 k는 최대 7)
dp[i]=dp[k];
라고 두면 된다.
왜냐하면 k를 만드는 수식에 느낌표만 붙이면 1을 더 사용하지 않고 i를 표현하는 수식이 완성되기 때문이다.

PART 2.

이제 i가 어떤 자연수의 팩토리얼이 아닐 때,
i는
1. e1+e2 형태로 덧셈으로 이어진 식이거나,
2. e1*e2 형태로 곱셈으로 이어진 식
무조건 둘 중 하나이다.

식 e1가 표현하는 수가 j이면
1. e2는 i-j를 표현하는 식이거나,
2. e2는 i/j를 표현하는 식이거나 (단, i는 j로 나뉘어 떨어지는 경우만)

따라서 j<i인 모든 자연수 j에 대해
dp[j]+d[i-j], dp[i/j]+dp[j] (i가 j로 나뉘어 떨어지는 경우)
들을 전부 계산한 뒤 이 중 가장 작은 값을 dp[i]로 설정하면 된다.

다음은 C언어로 구현한 코드이다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
int min(int n, int m)
{
    return (n < m) ? n : m;
}
 
 
int main()
{
    int n;
    scanf("%d"&n);
    //PART 0
    int dp[10005= { 0 };
    dp[0= 0;
    dp[1= 1;
    dp[2= 2;
    dp[3= 3;
    dp[4= 4;
    dp[5= 5;
    dp[6= 3;
    dp[7= 4;
    dp[8= 5;
 
    //PART 1
    int k = 2;
    for (int i = 3;i <= 7;i++)
    {
        k *= i;
        dp[k] = dp[i];
    }
 
    //PART 2
    for (int i = 9;i < 10001;i++)
    {
        if (dp[i])
            continue;
        dp[i] = 2100000000;
        for (int j = 1;j < i;j++)
        {
            dp[i] = min(dp[i], dp[i / j] + dp[j] + dp[i % j]);
 
            dp[i] = min(dp[i], dp[i - j] + dp[j]);
        }
    }
    printf("%d", dp[n]);
    
}
cs
 
 

시간복잡도는 O(n^2)이다.

'problem solving' 카테고리의 다른 글

백준 16888: 루트 게임  (0) 2023.02.24
백준 24678: 돌무더기 게임 1  (1) 2023.02.24
백준 26156: 나락도 락이다  (3) 2023.02.23
백준 11390: 맛있는 과자  (0) 2023.02.21
백준 19847: 여우 신탁  (0) 2023.02.21