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]
์ด๋ ๋ฐฐ์ด์ ์ ๋ถ ๋ง๋ค์ด์ ์ฌ์ฉํ๊ฒ ๋๋ฉด ์ต๋ ๋ฐฐ์ด์ ํฌ๊ธฐ๊ฐ 1000x10000๋ผ์ ๋ฉ๋ชจ๋ฆฌ ์ด๊ณผ๊ฐ ๋ฐ์ํ๋ค. ์ด์ฐจํผ Nํ๊ณผ N-1ํ 2๊ฐ์ ํ๋ง ์ฌ์ฉํ๊ธฐ ๋๋ฌธ์ dp๋ฅผ 2๊ฐ์ ํ์ผ๋ก ๋ง๋ค์ด์ ๋ฒ๊ฐ์ ์ฌ์ฉํ๋ ๋ฐฉ์์ ์ฐ๋ฉด ์ต๋ ๋ฐฐ์ด์ ํฌ๊ธฐ๊ฐ 2๋ง์ผ๋ก ๋ฉ๋ชจ๋ฆฌ ์ด๊ณผ๊ฐ ๋ฐ์ํ์ง ์์ ์ ์๋ค.
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]);
}
}