[BOJ] 3037. ํ˜ผ๋ž€ (๐Ÿฅ‡, DP/๋ˆ„์ ํ•ฉ)

lemythe423ยท2024๋…„ 3์›” 17์ผ
0

BOJ ๋ฌธ์ œํ’€์ด

๋ชฉ๋ก ๋ณด๊ธฐ
130/133
post-thumbnail

๐Ÿ”—

ํ’€์ด

N์€ ์ตœ๋Œ€ 1000์ด๋ฏ€๋กœ ๋ชจ๋“  ๊ฒฝ์šฐ์— ๋Œ€ํ•ด์„œ ๋ธŒ๋ฃจํŠธ ํฌ์Šค ๋ฐฉ์‹์œผ๋กœ ๊ตฌํ•˜๋Š” ๊ฒƒ์€ 1์ดˆ ๋‚ด์— ์—ฐ์‚ฐ์ด ๋ถˆ๊ฐ€๋Šฅํ•˜๋‹ค. ๋Œ€์‹  ๊ทœ์น™์„ ์ฐพ์•„๋ณด๊ธฐ๋กœ ํ–ˆ๋‹ค.

๊ฐ„๋‹จํ•˜๊ฒŒ N=3์— ๋Œ€ํ•ด ๊ฐ€๋Šฅํ•œ ๋ชจ๋“  ๊ฒฝ์šฐ์˜ ์ˆ˜๋ฅผ ๊ตฌํ•˜๋ฉด ์•„๋ž˜์™€ ๊ฐ™๋‹ค. ์ˆœ์„œ์— ๋”ฐ๋ผ ์ •๋ ฌํ•  ์ˆ˜ ์žˆ๋Š” ๊ฐ€์ง€์ˆ˜๋Š” Nx(N-1)/2 = 6๊ฐ€์ง€์ด๋‹ค. 6๊ฐ€์ง€ ๋ฐ–์— ์•ˆ ๋˜๊ธฐ ๋•Œ๋ฌธ์— ์ง๊ด€์ ์œผ๋กœ ๋ฐ”๋กœ ๊ตฌํ•  ์ˆ˜ ์žˆ๋‹ค.

์ด๋ฒˆ์—๋Š” N=4์— ๋Œ€ํ•ด ๊ตฌํ•ด๋ณด์•˜๋‹ค.

์šฐ์„  ๋งจ ์•ž์˜ ์ˆซ์ž๋ฅผ 1๋กœ ๊ณ ์ •ํ•˜๊ณ  ๊ตฌํ•˜๋Š” ๊ฒฝ์šฐ(์™ผ์ชฝ)๊ณผ ๋งจ ์•ž ์ˆซ์ž๋ฅผ 2๋กœ ๊ณ ์ •ํ•˜๊ณ  ๊ตฌํ•˜๋Š” ๊ฒฝ์šฐ(์˜ค๋ฅธ์ชฝ)๋กœ ๋‚˜๋ˆ ์„œ ๊ตฌํ–ˆ๋‹ค. ๋งจ ์•ž์ด 1๋กœ ๊ณ ์ •๋œ ๊ฒฝ์šฐ ๋‚˜๋จธ์ง€ 2,3,4์—์„œ ์„ธ ์ž๋ฆฌ๋ฅผ ๊ตฌํ•˜๋Š” ๊ฒฝ์šฐ๋Š” ์œ„์—์„œ ๊ตฌํ•œ N=3์ผ ๋•Œ์™€ ๋™์ผํ•˜๊ฒŒ ๊ตฌํ•  ์ˆ˜ ์žˆ๋‹ค. ์ˆซ์ž๊ฐ„์˜ ์ฐจ์ด๊ฐ’์ด ์ค‘์š”ํ•œ ๊ฒƒ์ด ์•„๋‹ˆ๋ผ ํฌ๊ณ  ์ž‘์Œ์ด ์ค‘์š”ํ•˜๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

๋งจ์•ž์ด 2๋กœ ๊ณ ์ •๋œ ๊ฒฝ์šฐ๋Š” ๊ฐ’์ด ๋‹ฌ๋ผ์ง€๊ฒŒ ๋˜๋Š”๋ฐ ๋งจ์•ž์— ํ•ญ์ƒ 2๊ฐ€ ์žˆ๊ณ  ๋’ค์—๋Š” ํ•ญ์ƒ 1์ด ์žˆ์„ ๊ฒƒ์ด๊ธฐ ๋•Œ๋ฌธ์— ๋ชจ๋“  ๊ฒฝ์šฐ์˜ ์ˆ˜์— (2,1)์ง์ด ์ถ”๊ฐ€๋˜๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

๋งจ์•ž์ด 3, 4์ธ ๊ฒฝ์šฐ ์—ญ์‹œ (3,2), (3,1)๊ณผ (4,2), (4,1), (4,3)์ด ์ถ”๊ฐ€๋œ๋‹ค. ๋งจ ์•ž์— ๋†“์ธ ์ˆซ์ž๊ฐ€ ๋‚˜๋จธ์ง€ ์ˆซ์ž๋“ค ๊ฐ€์šด๋ฐ ๋ช‡ ๋ฒˆ์งธ๋กœ ํฐ ๊ฐ€์— ๋”ฐ๋ผ ๋”ํ•ด์ง€๋Š” ์ˆซ์ž๊ฐ€ ๋Š˜์–ด๋‚˜๊ฒŒ ๋œ๋‹ค. ๊ทธ๋ฆผ์œผ๋กœ ์ •๋ฆฌํ•˜๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

๊ฒฐ๊ตญ dp[i][j]์— ํ•ด๋‹นํ•˜๋Š” ๊ฐ’์€ ๋งจ ์•ž์˜ ์ˆซ์ž๊ฐ€ ๋ณ€๊ฒฝ๋˜๋Š” ํšŸ์ˆ˜ ๋งŒํผ(k= 0 ~ N-1) dp[i-1][j-k] ๊ฐ’์„ ๊ณ„์† ๋”ํ•ด์ฃผ๋Š” ๊ฒƒ์ด๋‹ค. ๊ทธ๋ฆผ์—์„œ dp[4][3] ๊ฐ’์„ ๊ตฌํ•˜๋ฉด ์•„๋ž˜์™€ ๊ฐ™๋‹ค.

dp[4][3] = dp[3][3] + dp[3][2] + dp[3][1] + dp[d][0]

โŒ ์‹œ๊ฐ„ ์ดˆ๊ณผ

ํ•˜์ง€๋งŒ ์ ํ™”์‹๋Œ€๋กœ ๊ตฌํ•˜๋‹ˆ ์‹œ๊ฐ„ ์ดˆ๊ณผ๊ฐ€ ๋ฐœ์ƒํ–ˆ๋‹ค. ์šฐ์„  3์ค‘ for๋ฌธ์—์„œ O(N^2xM)๋กœ ์‚ฌ์‹ค์ƒ ์ด๋ฏธ N^2์—์„œ ์‹œ๊ฐ„ ์ดˆ๊ณผ๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ๋ฐ–์— ์—†์—ˆ๋‹ค.

import java.util.*;
import java.io.*;

public class Main {
    static final int DIVIDE = 1_000_000_007;
    public static void main(String[] args) throws IOException {
        Scanner sc = new Scanner(System.in);
        int N = sc.nextInt();
        int C = sc.nextInt();

        int[][] dp = new int[N+1][Math.min(C+1, (N*(N+1))/2 + 1)];
        dp[1][0] = 1;
        for (int i = 2; i <= N; i++) {
            for (int j = 0; j < i; j++) {
                for (int k = 0; k < Math.min(C+1, (i * (i-1)) / 2); k++) {
                    if (k+j > C) continue;
                    dp[i][k+j] += dp[i-1][k];
                    dp[i][k+j] %= DIVIDE;
                }
            }
        }

        // for (int i = 0; i < dp.length; i++) {
        //     System.out.println(Arrays.toString(dp[i]));
        // }

        System.out.println(dp[N][C]);
    }
}

๊ฒฐ๊ตญ ์ ํ™”์‹์„ ์žฌ์ •๋ฆฌํ•ด์„œ ํ’€ ์ˆ˜ ๋ฐ–์— ์—†์—ˆ๋‹ค. ํ•ด๋‹น ์ ํ™”์‹์„ ํ’€์–ด ์จ๋ณด๋ฉด ์•„๋ž˜์™€ ๊ฐ™์ด ์ค‘๋ณต๋˜๋Š” ๋ถ€๋ถ„๋“ค์ด ์žˆ๋Š” ๊ฒƒ์„ ์•Œ ์ˆ˜ ์žˆ๋‹ค.

dp[5][6]๋ฅผ dp[5][5]์™€ ์—ฐ๊ด€์ง€์–ด์„œ ์ •๋ฆฌํ•  ์ˆ˜ ์žˆ์„ ๊ฒƒ ๊ฐ™๋‹ค.

dp[5][6] = dp[4][6] + dp[5][5] - dp[4][1]

์ด๋•Œ dp[5][5]์— ์žˆ๋Š” dp[4][1] ๊ฐ’์„ ๋ฌด์—‡์œผ๋กœ ์ •์˜ํ•ด์•ผ ํ•˜๋Š”์ง€๊ฐ€ ๋ฌธ์ œ์ด๋‹ค. ๋‚˜๋จธ์ง€๋Š” ๋‹จ์ˆœํžˆ N-1 ๋˜๋Š” C-1์„ ํ•˜๋ฉด ๋˜๋Š” ๊ฐ’์ด์ง€๋งŒ N๊ณผ C๋ฅผ ์‚ฌ์šฉํ•ด์„œ dp[4][1]์„ ์ •์˜ํ•˜๋ ค๋ฉด ์–ด๋–ป๊ฒŒ ํ•ด์•ผํ• ๊นŒ๋ฅผ ๊ณ ๋ฏผํ–ˆ๋‹ค.

๊ทธ๋Ÿฐ๋ฐ k=0๋ถ€ํ„ฐ N-1๊นŒ์ง€ ๋”ํ•˜๋Š” ๊ฒƒ์ด๋ผ๊ณ  ํ–ˆ์œผ๋ฏ€๋กœ C-K์˜ ๊ฐ’์€ ์ฐจ๋ก€๋Œ€๋กœ 5, 4, 3, 2, 1์ด ๋  ๊ฒƒ์ด๊ณ  ๊ฒฐ๊ตญ dp[4][1]์—์„œ 1์˜ ๊ฐ’์€ K๊ฐ€ N-1(4)์ผ ๋•Œ์˜ C-K๊ฐ’์ด๋ผ๊ณ  ์ •์˜ํ•  ์ˆ˜ ์žˆ๋‹ค. ์—ฌ๊ธฐ์„œ๋Š” dp[5][5]๊ธฐ์ค€์ด๊ธฐ ๋•Œ๋ฌธ์— C=5์ด์ง€๋งŒ dp[5][6]์— ํ•ด๋‹น ๊ฐ’์„ ๋Œ€์ž…ํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” C=6์„ ๊ธฐ์ค€์œผ๋กœ ๊ณ„์‚ฐํ•ด์•ผ ํ•œ๋‹ค.

dp[4][1] = dp[N-1][C-N]์œผ๋กœ ์ •์˜ํ•  ์ˆ˜ ์žˆ๋‹ค

๊ฒฐ๊ตญ ์ •๋ฆฌํ•˜๋ฉด ์ง„์งœ ์ ํ™”์‹์€ ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

dp[N][C] = dp[N-1][C] + dp[N][C-1] - dp[N-1][C-N]

๐Ÿ“Œ ์ฃผ์˜ ์‚ฌํ•ญ

1๏ธโƒฃ ๋ฉ”๋ชจ๋ฆฌ ์ดˆ๊ณผ

์ด๋•Œ ๋ฐฐ์—ด์„ ์ „๋ถ€ ๋งŒ๋“ค์–ด์„œ ์‚ฌ์šฉํ•˜๊ฒŒ ๋˜๋ฉด ์ตœ๋Œ€ ๋ฐฐ์—ด์˜ ํฌ๊ธฐ๊ฐ€ 1000x10000๋ผ์„œ ๋ฉ”๋ชจ๋ฆฌ ์ดˆ๊ณผ๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค. ์–ด์ฐจํ”ผ Nํ–‰๊ณผ N-1ํ–‰ 2๊ฐœ์˜ ํ–‰๋งŒ ์‚ฌ์šฉํ•˜๊ธฐ ๋•Œ๋ฌธ์— dp๋ฅผ 2๊ฐœ์˜ ํ–‰์œผ๋กœ ๋งŒ๋“ค์–ด์„œ ๋ฒˆ๊ฐˆ์•„ ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ์‹์„ ์“ฐ๋ฉด ์ตœ๋Œ€ ๋ฐฐ์—ด์˜ ํฌ๊ธฐ๊ฐ€ 2๋งŒ์œผ๋กœ ๋ฉ”๋ชจ๋ฆฌ ์ดˆ๊ณผ๊ฐ€ ๋ฐœ์ƒํ•˜์ง€ ์•Š์„ ์ˆ˜ ์žˆ๋‹ค.

2๏ธโƒฃ ์Œ์ˆ˜๋ฅผ MOD๋กœ ๋‚˜๋ˆด์„ ๋•Œ ๋‚˜๋จธ์ง€

dp[i%2][j] = (dp[i%2][j-1] + dp[1-i%2][j] - (j >= i ? dp[1-i%2][j-i] : 0) + MOD) % MOD;

ํ•ด๋‹น ๊ฐ’์„ ๊ณ„์‚ฐํ•  ๋•Œ MOD์˜ ๋™์ž‘ ๋ฐฉ์‹์€ ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

(A+B-C)%MOD = (A%MOD) + (B%MOD) - (C%MOD)

๋ชจ๋“  ์—ฐ์‚ฐ์˜ ์ˆœ๊ฐ„์— ๋Œ€ํ•ด (A+B)๋Š” ํ•ญ์ƒ C๋ณด๋‹ค ํฌ์ง€๋งŒ MOD๋กœ ๋‚˜๋ˆ ์ง„ ๋‚˜๋จธ์ง€ ๊ฐ’์€ C๋ณด๋‹ค ์ž‘์•„์งˆ ์ˆ˜ ์žˆ๋‹ค. ๊ฒฐ๊ตญ ์ค‘๊ฐ„์— ์Œ์ˆ˜๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๋Š” ๊ฒƒ์ด๋‹ค. ๊ทธ๋ ‡๊ธฐ ๋•Œ๋ฌธ์— ์ œ๋Œ€๋กœ ๋œ ๊ฒฐ๊ณผ๊ฐ’์„ ์–ป๊ธฐ ์œ„ํ•ด์„œ๋Š” ํ•ญ์ƒ ๋‚˜๋จธ์ง€๊ฐ€ ์–‘์ˆ˜๊ฐ€ ๋‚˜์˜ฌ ์ˆ˜ ์žˆ๋„๋ก ๋ณด์žฅํ•ด์•ผ ํ•œ๋‹ค. ์ด๋ฅผ ๋ณด์žฅํ•˜๊ธฐ ์œ„ํ•ด ์Œ์ˆ˜๊ฐ€ ๋‚˜์˜ฌ ๊ฒฝ์šฐ๋ฅผ ๋Œ€๋น„ํ•ด MOD๊ฐ’์„ ํ•œ ๋ฒˆ ๋”ํ•œ ํ›„ ๋‚˜๋ˆ ์ฃผ๊ฒŒ ๋œ๋‹ค.

โœ… ํ†ต๊ณผ ์ฝ”๋“œ

import java.util.*;
import java.io.*;

public class Main {
    static final int MOD = 1_000_000_007;
    public static void main(String[] args) throws IOException {
        Scanner sc = new Scanner(System.in);
        int N = sc.nextInt();
        int C = sc.nextInt();

        long[][] dp = new long[2][C+1];
        dp[0][0] = 1;
        for (int i = 1; i <= N; i++) {
            dp[i%2][0] = 1;
            for (int j = 1; j <= C; j++) {
                dp[i%2][j] = (dp[i%2][j-1] + dp[1-i%2][j] - (j >= i ? dp[1-i%2][j-i] : 0) + MOD) % MOD;
                // dp[i%2][j] %= MOD;
            }
        }
        System.out.println(dp[N%2][C]);
    }
}

์ฐธ๊ณ 

profile
์•„๋ฌด๋ง์ด๋‚˜ํ•˜๊ธฐ

0๊ฐœ์˜ ๋Œ“๊ธ€