[BOJ] 18858 : ํ๋ จ์๋ก ๊ฐ๋ ๋
๋ฌธ์ ๋งํฌ
https://www.acmicpc.net/problem/18858
18858๋ฒ: ํ๋ จ์๋ก ๊ฐ๋ ๋
1 ์ด์ M ์ดํ์ ์ ์๋ก ์ด๋ฃจ์ด์ง ๊ธธ์ด N์ ์์ด ์ค ๋ ผ์ฐ์ธ ๊ฒ์ ๊ฐ์๋ฅผ 998,244,353์ผ๋ก ๋๋ ๋๋จธ์ง๋ฅผ ์ถ๋ ฅํ๋ค.
www.acmicpc.net
๋ ผ์ฐ(Non-์ฐ)์ธ ์์ด์ด ๋ช ๊ฐ์ธ์ง ์ถ๋ ฅํ๋ ๋ฌธ์ .
ํ์ด
๋ ผ์ฐ์ด๋ Non-์ฐ ์ฆ ์ฐ์ด ์๋ ์์ด์ ์๋ฏธํ๋ค. a1 < a2 > a3 ์ฒ๋ผ ์ฌ๋ผ๊ฐ๋ค ๋ด๋ ค๊ฐ๋ ํํ์ ์์ด์ ์ฐ์ด๋ผ๊ณ ๋ถ๋ฅด๊ธฐ๋ก ํ๋ค.
์ฌ๊ธฐ์ DP๋ฐฐ์ด์ ์ด๋ป๊ฒ ์ ์ธํ ์ง๊ฐ ๊ด๊ฑด์ธ๋ฐ, ์์ด์ i๋ฒ์งธ ์์ ๋ํด์ 3๊ฐ์ง์ ๊ฒฝ์ฐ๋ก ๋๋์ด์ ์๊ฐํ ์ ์๋ค.
1. i-1๋ฒ์งธ ์์ ๋น๊ตํ์ ๋ i๋ฒ์งธ ์๊ฐ ๋ ํฐ ๊ฒฝ์ฐ. ์ฆ, ์ฌ๋ผ์จ ๊ฒฝ์ฐ(์ค๋ฅด๋ง)
2. i-1๋ฒ์งธ ์์ ๋น๊ตํ์ ๋ i๋ฒ์งธ ์๊ฐ ๋ ์์ ๊ฒฝ์ฐ. ์ฆ, ๋ด๋ ค์จ ๊ฒฝ์ฐ(๋ด๋ฆฌ๋ง)
3. i-1๋ฒ์งธ ์์ i๋ฒ์งธ ์๊ฐ ๊ฐ์ ๊ฒฝ์ฐ. ์ฆ, ๊ทธ๋๋ก(ํ์ง)
DP๋ฐฐ์ด์ DP[1~M][์์ด์ ๋ช๋ฒ์งธ ์ซ์์ธ์ง(1~N)][์ค๋ฅด๋ง์ธ์ง, ๋ด๋ฆฌ๋ง์ธ์ง ํ์ง์ธ์ง]
๋๋ ์ค๋ฅด๋ง์ 0, ํ์ง๋ฅผ 1, ๋ด๋ฆฌ๋ง์ 2๋ก ์ ํ๋ค.
1. i-1๋ฒ์งธ ์ < i๋ฒ์งธ ์์ธ ๊ฒฝ์ฐ์๋ ์ฆ i-1 -> i ๊ฐ ์ค๋ฅด๋ง์ธ ๊ฒฝ์ฐ์๋ i-2 -> i-1 ์ด ์ค๋ฅด๋ง์ด๋ ํ์ง์ด๋ ๋ด๋ฆฌ๋ง์ด๋ ์๊ด์๋ค. ์ค๋ฅด๋ง -> ์ค๋ฅด๋ง, ํ์ง -> ์ค๋ฅด๋ง, ๋ด๋ฆฌ๋ง -> ์ค๋ฅด๋ง ๋ชจ๋ ๊ฐ๋ฅํ๊ธฐ ๋๋ฌธ์ด๋ค.
2. i-1๋ฒ์งธ ์ = i๋ฒ์งธ ์ ์ธ ๊ฒฝ์ฐ. ์ฆ, i-1 -> i ๊ฐ ํ์ง์ธ ๊ฒฝ์ฐ์๋ ์ญ์ i-2 -> i-1 ์ ์ค๋ฅด๋ง, ํ์ง, ๋ด๋ฆฌ๋ง ๋ชจ๋ ์๊ด์๋ค.
์ค๋ฅด๋ง -> ํ์ง, ํ์ง -> ํ์ง, ๋ด๋ฆฌ๋ง -> ํ์ง ๋ชจ๋ ๊ฐ๋ฅํ๊ธฐ ๋๋ฌธ์ด๋ค.
3. i-1๋ฒ์งธ ์ > i๋ฒ์งธ ์ ์ธ ๊ฒฝ์ฐ. ์ฆ, i-1 -> i๊ฐ ๋ด๋ฆฌ๋ง์ธ ๊ฒฝ์ฐ. ์ด๋๋ ๋ถ๊ฐ๋ฅํ ์ํฉ์ด ๋ฐ์ํ๋ค. ๋ง์ฝ i-2 -> i-1์ด ์ค๋ฅด๋ง์ด์๋ค๋ฉด i-2 -> i-1 -> i ๋ ์ค๋ฅด๋ง -> ๋ด๋ฆฌ๋ง์ผ๋ก ์ฐ์ด ํ์ฑ๋๋ค. ๊ทธ๋ ๊ธฐ ๋๋ฌธ์ i-2 -> i-1 ์ด ํ์ง, ๋๋ ๋ด๋ฆฌ๋ง์ธ ๊ฒฝ์ฐ๋ง ์ ํจํ ๊ฒ์ผ๋ก ํ๋จํ๋ค.
for (int i = 2; i <= N; i++) {
for (int j = 1; j <= M; j++) {
for (int k = 1; k < j; k++) {
DP[j][i][0] += (DP[k][i - 1][0] + DP[k][i - 1][1] + DP[k][i - 1][2]);
DP[j][i][0] %= mod;
}
DP[j][i][1] += (DP[j][i - 1][0] + DP[j][i - 1][1] + DP[j][i - 1][2]);
DP[j][i][1] %= mod;
for (int k = M; k > j; k--) {
DP[j][i][2] += (DP[k][i - 1][1] + DP[k][i - 1][2]);
DP[j][i][2] %= mod;
}
}
}
๊ทธ๋ ๊ฒ ์ฝ๋๋ฅผ ์์ํด๋ณด๋ฉด ์ ํ์์ ์ด๋ ๊ฒ ๋๋ค.
๊ทธ๋ฆฌ๊ณ N์ด ๋ง์ฝ 1๋๋ 2๋ผ๋ฉด ์ฐ์ด ํ์ฑ๋ ์๊ฐ ์๊ธฐ ๋๋ฌธ์
if (N == 1) {
cout << M << "\n";
return 0;
}
else if (N <= 2) {
cout << M * M << "\n";
return 0;
}
์ด๊ธฐ์ ์์ธ๋ฅผ ๊ฑธ์ด์ฃผ์๋ค.
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
32
33
34
|
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <cstdio>
#include <string.h>
#include <string>
#include <stack>
#include <vector>
#include <math.h>
#include <queue>
#include <climits>
#include <algorithm>
#include <iomanip>
#include <map>
#define mod 998244353
using namespace std;
typedef long long ll;
typedef priority_queue<pair<int, pair<int, int>>, vector<pair<int, pair<int, int>>>, greater<pair<int, pair<int, int>>>> Priority_queue;
const int INF = INT_MAX;
const int MAX_N = 1000 + 5;
int N, M;
ll DP[105][MAX_N][3];
int main(void){
ios_base::sync_with_stdio(false);
cin.tie(NULL);
cin >> N >> M;
if (N == 1) {
cout << M << "\n";
return 0;
}
else if (N <= 2) {
cout << M * M << "\n";
return 0;
}
for (int i = 1; i <= M; i++) {
DP[i][2][0] = i - 1;
DP[i][2][1] = 1;
DP[i][2][2] = M - i;
}
for (int i = 2; i <= N; i++) {
for (int j = 1; j <= M; j++) {
for (int k = 1; k < j; k++) {
DP[j][i][0] += (DP[k][i - 1][0] + DP[k][i - 1][1] + DP[k][i - 1][2]);
DP[j][i][0] %= mod;
}
DP[j][i][1] += (DP[j][i - 1][0] + DP[j][i - 1][1] + DP[j][i - 1][2]);
DP[j][i][1] %= mod;
for (int k = M; k > j; k--) {
DP[j][i][2] += (DP[k][i - 1][1] + DP[k][i - 1][2]);
DP[j][i][2] %= mod;
}
}
}
ll ans = 0;
for (int i = 1; i <= M; i++) {
ans += (DP[i][N][0] + DP[i][N][1] + DP[i][N][2]);
ans %= mod;
}
cout << ans << "\n";
return 0;
}
|
cs |