10844๋ฒ: ์ฌ์ด ๊ณ๋จ ์
์ฒซ์งธ ์ค์ ์ ๋ต์ 1,000,000,000์ผ๋ก ๋๋ ๋๋จธ์ง๋ฅผ ์ถ๋ ฅํ๋ค.
www.acmicpc.net
์๊ณ ๋ฆฌ์ฆ [์ ๊ทผ ๋ฐฉ๋ฒ]
๋ฌธ์ ์ค๋ช ์ ๋ณด๋ฉด ์ผ๋จ ์๋ฆฟ์๊ฐ 100, ์ฆ 100์งธ์๋ฆฌ ์๊น์ง ์ฃผ์ด์ง๋ ๊ธฐ๋ณธ ํ์์ longํ์ ์ผ๋ก ํด์ค๋ค๊ณ ๊ฐ์ ํ๊ณ ์ค๋ช ํ๊ฒ ๋ค. ๋ํ ๋ฌธ์ ์์ ๊ฐ์ฅ ์ค์ํ ํฌ์ธํธ๋ '์ธ์ ํ ๋ชจ๋ ์๋ฆฟ์๊ฐ 1์ฉ ์ฐจ์ด๊ฐ ๋๋ค'๋ ๊ฒ์ด ํฌ์ธํธ.
์ฌ๊ธฐ์ ์ ์ํด์ผ ํ ์ ์ด ์๋๋ฐ ๋ค์ ๋ ๊ฐ์ง๋ฅผ ์กฐ์ฌํด์ผ ํ๋ค.
1) N๋ฒ์งธ ์๋ฆฟ์์ ์๋ฆฟ๊ฐ์ด 0์ธ ๊ฒฝ์ฐ : ๋ค์ ์๋ฆฟ์์ ์๋ฆฟ๊ฐ์ 1๋ฐ์ ์ฌ ์ ์๋ค.
2) N๋ฒ์งธ ์๋ฆฟ์์ ์๋ฆฟ๊ฐ์ด 9์ธ ๊ฒฝ์ฐ : ๋ค์ ์๋ฆฟ์์ ์๋ฆฟ๊ฐ์ 8๋ฐ์ ์ฌ ์ ์๋ค.
์ฆ, 10 ๋ค์์ ๋ถ์ ์ ์๋ ์๋ 1๋ฐ์ ์์ผ๋ฏ๋ก 101 ์ด ๋๋ ๊ฒ์ด๊ณ , ๋ง์ฝ 19๊ฐ ์จ๋ค๋ฉด 8๋ฐ์ ์ฌ ์ ์์ผ๋ฏ๋ก 198 ์ด ๋๋ ๊ฒ์ด๋ค. ๊ทธ ์ธ์ ๊ฐ(2~8)์ ๊ฐ ๊ฐ๋ณด๋ค -1 ๋๋ +1 ์ธ ๊ฐ์ ๊ฐ์ง ์ ์๋ค.
๊ทธ๋ผ ์๋ฆฟ๊ฐ์ 0~9๋ฅผ ๊ฐ์ง ์ ์๊ณ , N๊ฐ์ ์๋ฆฟ๊ฐ์ ํํํด์ผํ๋ฏ๋ก 2์ฐจ์ ๋ฐฐ์ด์ด ํ์ํ๋ค.
// N์๋ฆฟ์์ ๊ฐ๊ฐ์ ์๋ฆฟ๊ฐ(0~9)๋ฅผ ์๋ฏธ
Long[] dp = new Long[N + 1][10]
(์๋ฆฟ์๋ ๋ฐฐ์ด์ ๊ฒฝ์ฐ 0๋ถํฐ ์์ํ๊ธฐ ๋๋ฌธ์ N+1)
[Top-Down]
์ฌ๊ท๋ฅผ ์ฐ๊ธฐ ์ํด ๋ ๊ฐ์ง ๋ณ์๋ฅผ ๋ ๊ฒ์ธ๋ฐ, ์๋ฆฟ๊ฐ์ ํํ ํ ๋ณ์์ธ digit, ์๋ฆฟ๊ฐ์ ํํ ํ ๋ณ์์ธ val, ์ด๋ ๊ฒ ๋ ๊ฐ๋ฅผ ์ด์ฉ ํ ๊ฒ์ด๋ค.
๊ทธ๋ฆฌ๊ณ ์ฌ๊ทํธ์ถ์ ์๋ฆฟ๊ฐ์ ๋ฐ๋ผ ์๋ฆฟ๊ฐ์ด 0์ด๋ผ๋ฉด ๋ค์์ ์ฌ ์๋ฆฟ๊ฐ์ 1๋ก, 9๋ผ๋ฉด 8๋ก ํธ์ถํด์ฃผ๊ณ , ๊ทธ ์ธ์ ๊ฒฝ์ฐ๋ val-1, val+1 ๋ ๋ค ๊ฐ๋ฅํ๋ ๋ ๋ค ํธ์ถํ์ฌ ๊ฒฝ์ฐ์ ์๋ฅผ ํฉํ๋ฉด ๋๋ค.
/*
digit ๋ ์๋ฆฟ์, val์ ์๋ฆฟ๊ฐ์ ์๋ฏธํจ
์ฒซ์งธ ์๋ฆฌ์๋ ๊ฐ val์ด ๋์ด๊ธฐ ๋๋ฌธ์
๊ฒฝ์ฐ์ ์๋ 1๋ฐ์ ์๋ค. ์ฆ, dp[1]์ ๊ฐ ์๋ฆฟ๊ฐ์
1๋ก ์ด๊ธฐํ ๋์ด์์ด์ผํ๋ค.
*/
static long recur(int digit, int val) {
// ์ฒซ์งธ ์๋ฆฌ์์ ๋์ฐฉํ๋ค๋ฉด ๋์ด์ ํ์ํ ํ์ ์์
if(digit == 1) {
return dp[digit][val];
}
// ํด๋น ์๋ฆฌ์์ val๊ฐ์ ๋ํด ํ์ํ์ง ์์์ ๊ฒฝ์ฐ
if(dp[digit][val] == null) {
// val์ด 0์ผ๊ฒฝ์ฐ ๋ค์์ 1๋ฐ์ ๋ชป์ด
if(val == 0) {
dp[digit][val] = recur(digit - 1 ,1);
}
// val์ด 1์ผ๊ฒฝ์ฐ ๋ค์์ 8๋ฐ์ ๋ชป์ด
else if(val== 9) {
dp[digit][val] = recur(digit - 1, 8);
}
// ๊ทธ ์ธ์ ๊ฒฝ์ฐ๋ val-1๊ณผ val+1 ๊ฐ์ ๊ฒฝ์ฐ์ ์๋ฅผ ํฉํ ๊ฒฝ์ฐ์ ์๊ฐ ๋จ
else {
dp[digit][val] = recur(digit - 1, val - 1) + recur(digit - 1, val + 1);
}
}
return dp[digit][val];
}
dp[1][0], dp[1][1], โฏ ,dp[1][9] ๋ 1๋ก ์ด๊ธฐํ ๋์ด์์ด์ผ ํ๋ค.
recur๋ผ๋ ํจ์๋ฅผ ํ์ํ ๋, digit ๋ฒ์งธ ์๋ฆฟ์์ ์๋ฆฟ๊ฐ val์ ๋ํ์ฌ ํด๋น ์๋ฆฟ์์ ๊ฒฝ์ฐ์ ์๊ฐ ์๋, ์ฆ dp[digit][val]์ด null ์ธ ๊ฒฝ์ฐ ์๋ฆฟ๊ฐ์ ๋ฐ๋ผ 3๊ฐ์ง ๊ฒฝ์ฐ๋ก ๋๋์ด digit-1๋ฒ์งธ ์๋ฆฟ์๋ก ์ฌ๊ทํธ์ถ์ ํด์ค๋ค.
์ฝ๊ฒ ๋งํ๋ฉด N ๋ฒ์งธ ์๋ฆฟ์์ ์๋ฆฟ๊ฐ์ด ์์ผ๋ฉด N-1๋ฒ์งธ ์๋ฆฟ์๋ฅผ ํ์ํ๊ณ , N-1 ๋ ์์ผ๋ฉด N-1์ -1 ๋ฒ์งธ ์๋ฆฟ์๋ฅผ ํ์ํ์ฌ ๊ฐ์ด ์์ ๋ ๊น์ง ์ฐพ์๋๊ฐ๋ ๋ฐฉ์์ธ ๊ฒ์ด๋ค.
[Bottom-Up]
long[][] dp = new long[N + 1][10];
// ์ฒซ ๋ฒ์งธ ์๋ฆฟ์๋ ์ค๋ฅธ์ชฝ ๋งจ ๋์ ์๋ฆฟ์์ด๋ฏ๋ก ๊ฒฝ์ฐ์ ์๊ฐ 1๊ฐ๋ฐ์ ์์
for(int i = 1; i < 10; i++) {
dp[1][i] = 1;
}
// ๋ ๋ฒ์งธ ์๋ฆฟ์๋ถํฐ N๊น์ง ํ์
for(int i = 2; i <= N; i++) {
// i๋ฒ์งธ ์๋ฆฟ์์ ์๋ฆฟ๊ฐ๋ค์ ํ์ (0~9)
for(int j = 0; j < 10; j++) {
// j=0, ์ฆ ์๋ฆฟ๊ฐ์ด 0์ด๋ผ๋ฉด ์ด์ ์๋ฆฟ์์ ์ฒซ๋ฒ์งธ ์๋ฆฟ์๋ง ๊ฐ๋ฅ
if(j == 0) {
dp[i][0] = dp[i - 1][1];
}
// j=9๋ผ๋ฉด ์ด์ ์๋ฆฟ์๋ 8๋ง ๊ฐ๋ฅ
else if (j == 9) {
dp[i][9] = dp[i - 1][8];
}
// ๊ทธ ์ธ์ ๊ฒฝ์ฐ ์ด์ ์๋ฆฟ์์ ์๋ฆฟ๊ฐ +1, -1 ์ ํฉ์ด ๋จ
else {
dp[i][j] = (dp[i - 1][j - 1] + dp[i - 1][j + 1]);
}
}
}
์์ฐํ ํ๋ฉด ์๋ฆฟ์๊ฐ ๊ฑฐ๊พธ๋ก ๋์ด์๋๋ฐ, ์ด์ฐจํผ ๊ฒฝ์ฐ์ ์๋ฅผ ๊ตฌํ๋ ๊ฒ์ด๊ธฐ ๋๋ฌธ์ ํฌ๊ฒ ๋ฌธ์ ๋์ง ์๋๋ค.
ํ์ด ๋ฐ ์ฝ๋
- ๋ฐฉ๋ฒ 1 : [Scanner + Top-Down]
import java.util.Scanner;
public class Main {
static Long[][] dp;
static int N;
final static long MOD = 1000000000;
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
N = in.nextInt();
dp = new Long[N + 1][10];
// ์ฒซ๋ฒ์งธ ์๋ฆฟ์๋ 1๋ก ์ด๊ธฐํ
for(int i = 0; i < 10; i++) {
dp[1][i] = 1L;
}
long result = 0;
// ๋ง์ง๋ง ์๋ฆฟ์์ธ 1~9๊น์ง์ ๊ฒฝ์ฐ์ ์๋ฅผ ๋ชจ๋ ๋ํด์ค๋ค.
for(int i = 1; i <= 9; i++) {
result += recur(N, i);
}
System.out.println(result % MOD);
}
/*
dist ๋ ์๋ฆฟ์, val์ ์๋ฆฟ๊ฐ์ ์๋ฏธํจ
์ฒซ์งธ ์๋ฆฌ์๋ ๊ฐ val์ด ๋์ด๊ธฐ ๋๋ฌธ์
๊ฒฝ์ฐ์ ์๋ 1๋ฐ์ ์๋ค. ์ฆ, dp[1]์ ๊ฐ ์๋ฆฟ๊ฐ์
1๋ก ์ด๊ธฐํ ๋์ด์์ด์ผํ๋ค.
*/
static long recur(int digit, int val) {
// ์ฒซ์งธ ์๋ฆฌ์์ ๋์ฐฉํ๋ค๋ฉด ๋์ด์ ํ์ํ ํ์ ์์
if(digit == 1) {
return dp[digit][val];
}
// ํด๋น ์๋ฆฌ์์ val๊ฐ์ ๋ํด ํ์ํ์ง ์์์ ๊ฒฝ์ฐ
if(dp[digit][val] == null) {
// val์ด 0์ผ๊ฒฝ์ฐ ๋ค์์ 1๋ฐ์ ๋ชป์ด
if(val == 0) {
dp[digit][val] = recur(digit - 1 ,1);
}
// val์ด 1์ผ๊ฒฝ์ฐ ๋ค์์ 8๋ฐ์ ๋ชป์ด
else if(val== 9) {
dp[digit][val] = recur(digit - 1, 8);
}
// ๊ทธ ์ธ์ ๊ฒฝ์ฐ๋ val-1๊ณผ val+1 ๊ฐ์ ๊ฒฝ์ฐ์ ์๋ฅผ ํฉํ ๊ฒฝ์ฐ์ ์๊ฐ ๋จ
else {
dp[digit][val] = recur(digit - 1, val - 1) + recur(digit - 1, val + 1);
}
}
return dp[digit][val] % MOD;
}
}
์ฐธ๊ณ ๋ก MOD๋ 10์ต์ผ๋ก ์ด๊ธฐํ ๋์ด์๊ณ , ๋ถ๋ช ํ ๋ฌธ์ ์์ '10์ต์ผ๋ก ๋๋ ๋๋จธ์ง ๊ฐ'์ ์ถ๋ ฅํ๋ผ๊ณ ํ๋ค. N์ด ์ต๋ 100, ์ฆ ์๋ฆฟ์๋ง 100์๋ฆฌ๋ผ ๊ฒฝ์ฐ์ ์์ผ์ง๋ผ๋ longํ์ ์ ๋ฒ์ด๋ ์ ์๋ค. ๋๋ฌธ์ long ๋ฒ์์์ ๋ฒ์ด๋์ง ์๋๋ก ๊ฐ return๋ง๋ค ๋๋จธ์ง๊ฐ์ return์์ผ์ฃผ์ด์ผ ํ๋ค.
- ๋ฐฉ๋ฒ 2 : [Scanner + Bottom-Up]
import java.util.Scanner;
public class Main {
final static long mod = 1000000000;
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int N = in.nextInt();
long[][] dp = new long[N + 1][10];
// ์ฒซ ๋ฒ์งธ ์๋ฆฟ์๋ ์ค๋ฅธ์ชฝ ๋งจ ๋์ ์๋ฆฟ์์ด๋ฏ๋ก ๊ฒฝ์ฐ์ ์๊ฐ 1๊ฐ๋ฐ์ ์์
for(int i = 1; i < 10; i++) {
dp[1][i] = 1;
}
// ๋ ๋ฒ์งธ ์๋ฆฟ์๋ถํฐ N๊น์ง ํ์
for(int i = 2; i <= N; i++) {
// i๋ฒ์งธ ์๋ฆฟ์์ ์๋ฆฟ๊ฐ๋ค์ ํ์ (0~9)
for(int j = 0; j < 10; j++) {
// j=0, ์ฆ ์๋ฆฟ๊ฐ์ด 0์ด๋ผ๋ฉด ์ด์ ์๋ฆฟ์์ ์ฒซ๋ฒ์งธ ์๋ฆฟ์๋ง ๊ฐ๋ฅ
if(j == 0) {
dp[i][0] = dp[i - 1][1] % mod;
}
// j=9๋ผ๋ฉด ์ด์ ์๋ฆฟ์๋ 8๋ง ๊ฐ๋ฅ
else if (j == 9) {
dp[i][9] = dp[i - 1][8] % mod;
}
// ๊ทธ ์ธ์ ๊ฒฝ์ฐ ์ด์ ์๋ฆฟ์์ ์๋ฆฟ๊ฐ +1, -1 ์ ํฉ์ด ๋จ
else {
dp[i][j] = (dp[i - 1][j - 1] + dp[i - 1][j + 1]) % mod;
}
}
}
long result = 0;
// ๊ฐ ์๋ฆฟ๊ฐ๋ง๋ค์ ๊ฒฝ์ฐ์ ์๋ฅผ ๋ชจ๋ ๋ํด์ค๋ค.
for(int i = 0; i < 10; i++) {
result += dp[N][i];
}
System.out.println(result % mod);
}
}