반응형

문제 출처 :


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



알고리즘 분석 :


문제 해결에 필요한 사항

1. Dynamic Programming

2. 점화식 세우는 방법


전형적인 DP 문제이다.


dp[i][j]의 의미는 다음과 같다.


왼쪽부터 i번째 수가 j일때 그때의 dp값이라고 정의한다.


예를들어 

dp[2][3]은 ㅁ3ㅁㅁ... 이라고 생각할 수 있다.


dp[5][7]은 ㅁㅁㅁㅁ7ㅁㅁ... 이라고 생각할 수 있다.


dp[1][i]는 모두 1이 된다. 왜냐면 첫번째 자리에서의 줄어들지 않는 수는 모두 1개이기 때문이다.


dp[1][0] 은 숫자 0이 차지할것이고


dp[1][1] 은 숫자 0이 차지할것이고


...

dp[1][9] 는 숫자 9가 차지할것이기 때문이다.



이제 dp를 구해보자.


이때 아래의 코드 처럼 dp[i][j] += dp[i-1][k]가 왜 성립하는지 알아보자.


dp[i][j]를 구하기 위해서는 이전의 i-1의 값들을 알아야한다.


이때 dp[i-1][~]에 대해 모든 값을 더하면 안되고, 줄어들지 않는 수에 대해서만 더해주어야 한다.


예를들어 dp[4][3]을 구하기 위해서는 dp[3][0] + dp[3][1] + dp[3][2] + dp[3][3]에 대해서만 해야한다.


즉, ㅁㅁㅁ3이 되기 위해서는


ㅁㅁ0

ㅁㅁ1

ㅁㅁ2

ㅁㅁ3 에 대한 dp값만 이용해야 한다는 의미이다. 


이 dp값만 이용해야 결국


ㅁㅁ03

ㅁㅁ13

ㅁㅁ23

ㅁㅁ33에 대한 값을 모두 알 수 있기 때문이다.












소스 코드 : 


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
#include <iostream>
#include <cstdio>

 
using namespace std;
 
typedef long long ll;
 
ll dp[65][11];
 
int main()
{
    for (int i = 0; i <= 9; i++)
        dp[1][i] = 1;
 
    for (int i = 2; i <= 64; i++)
        for (int j = 0; j <= 9; j++)
            for(int k = 0; k <= j; k++)
                dp[i][j] += dp[i - 1][k];
 
    int tc;
    scanf("%d"&tc);
 
    while (tc--)
    {
        int n;
        scanf("%d"&n);
 
        ll ans = 0;
 
        for (int i = 0; i <= 9; i++)
            ans += dp[n][i];
 
        printf("%lld\n", ans);
    }
    return 0;
}
 
//                                                       This source code Copyright belongs to Crocus
//                                                        If you want to see more? click here >>
Crocus


반응형

'Applied > 알고리즘 문제풀이' 카테고리의 다른 글

[7785번] 회사에 있는 사람  (0) 2017.10.10
[5525번] IOIOI  (0) 2017.10.10
[9613번] GCD 합  (0) 2017.10.09
[10473번] 인간 대포  (0) 2017.10.09
[1011번] Fly me to the Alpha Centauri  (0) 2017.10.09