쉬운 계단 수
45656
이 수는 모든 자리수의 차이가 1이 난다. 이런 수가 계단수.
첫째 줄에 N이 주어지고 N은 1<=N<=100
10^100까지 커질 수 있다. 브루트포스로 할 수 있는 크기가 아니다.
이걸 알고서도 점화식 떠오르는게 없어서 브루트포스처럼 bottom-up으로 푸는 점화식을 생각했다.
D[N] : N의 계단 수인지 아닌지
S[N] : N의 자리수
D[N] = D[S[0] + S[1]] || D[S[1] + S[2]] || D[S[n-2] + S[n-1]]
// D[N]이 true면 cnt++;
n이 10^100인 경우, 최악의 경우 10^99 * 10^100 인데, 시간초과 날 수 밖에 없다.
걍 풀이를 보자.
D[N]
=> 길이가 N인 계단수.
위 점화식은 마지막 수에 대한 정보를 담고 있지 않다. (갑자기?)
점화식을 정의하기 위해 자리수별로 점화식을 세우려는 의도같다.
D[N][L]
: 마지막 수가 L이고 길이가 L인 계단 수
? ? L+1 | L-1 L
[1][2]... [N-1] [N]
L앞에 올 수 있는 수는 L-1, L+1인데, 이 때 계단 수는 D[N-1][L+1]
, D[N-1][L-1]
즉, D[N][L] = D[N-1][L-1] + D[N-1][L+1]
풀어보자.
long long dp[101][10];
long long n;
cin>>n;
long long size = n;
long long mod = 1000000000;
// fill_n(dp, size, 0); // 0: 미정, 1: true, -1: false
for(int i = 1; i<=9; i++) {
dp[1][i] = 1;
}
for(int i = 2; i<=size; i++) {
for(int j = 0; j<=9; j++) {
dp[i][j] = 0;
if(j-1>=0) {
dp[i][j] += dp[i-1][j-1];
}
if(j+1<=9) {
dp[i][j] += dp[i-1][j+1];
}
dp[i][j] %= mod;
}
}
long long result = 0;
for(int i = 0; i<=9; i++) {
result += dp[size][i];
}
cout<<result % mod<<endl;
Summary
자리 수 문제는 자리수 별로 점화식을 세워서 풀 수 있다는 생각을 해야겠다.
Last updated
Was this helpful?