Notice
Recent Posts
Recent Comments
Link
250x250
«   2025/07   »
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
Archives
Today
Total
관리 메뉴

피너클의 it공부방

백준 25421 조건에 맞는 정수의 개수 (c++) : 피너클 본문

백준

백준 25421 조건에 맞는 정수의 개수 (c++) : 피너클

피너클 2022. 8. 16. 17:25
728x90
반응형

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

 

25421번: 조건에 맞는 정수의 개수

2개의 자릿수를 갖고 첫 번째 자리의 숫자와 두 번째 자리의 숫자의 차이가 2보다 작거나 같은 양의 정수 11, 12, 13, 21, 22, 23, 24, 31, 32, ... , 97, 98, 99가 A에 해당된다. 따라서 정답은 39이다.

www.acmicpc.net

다이나믹 문제다.

탑다운으로 풀려고 했지만 함수 호출량이 너무 많은거 같아 바텀업으로 풀게됬다.

int n;
long long dp[10][100001];
long long MOD = 987654321;

사용할 변수다.

cin >> n;
memset(dp, 0, sizeof(dp));
long long ans = 0;
for (int i = 1; i <= 9; i++) {
    dp[i][1] = 1;
}

값을 입력받고 dp를 0으로 초기화한뒤 dp[i][1] = 1로 바꾼다.

dp[9][10]은 10의 자릿수에서 10이 나온 횟수를 의미한다.

dp[1][1]이라면 1의 자릿수에서 1이 나온 횟수니 1이 된다.

for (int i = 2; i <= n; i++) {
    for (int j = 1; j <= 9; j++) {
        for (int k = -2; k <= 2; k++) {
            if (1 <= j + k && j + k <= 9) {
                dp[j][i] += dp[j + k][i - 1];
                dp[j][i] %= MOD;
            }
        }
    }
}

그후 n의 자릿수까지 1부터 9까지 하나 하나 확인하며 나아간다.

만약 j + k가 범위 안에 있다면 dp[j][i]에 dp[j + k][i - 1]을 더하고 MOD로 나눈다.

for (int i = 1; i <= 9; i++) ans = (ans + dp[i][n]) % MOD;

cout << ans << endl;

그후 ans에 하나씩 더하고 MOD로 나눈뒤 출력하면 된다.

#include <iostream>
#include <algorithm>
#include <cstring>

using namespace std;

int n;
long long dp[10][100001];
long long MOD = 987654321;

int main()
{
	ios::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);

	cin >> n;
	memset(dp, 0, sizeof(dp));
	long long ans = 0;
	for (int i = 1; i <= 9; i++) {
		dp[i][1] = 1;
	}
	for (int i = 2; i <= n; i++) {
		for (int j = 1; j <= 9; j++) {
			for (int k = -2; k <= 2; k++) {
				if (1 <= j + k && j + k <= 9) {
					dp[j][i] += dp[j + k][i - 1];
					dp[j][i] %= MOD;
				}
			}
		}
	}
	for (int i = 1; i <= 9; i++) ans = (ans + dp[i][n]) % MOD;

	cout << ans << endl;
}

전체코드다.

728x90
반응형
Comments