BOJ 24945 Copy ans Paste 3
·635 words·3 mins
๐ ๋ฌธ์ ์ ๋ณด # ๋งํฌ: https://www.acmicpc.net/problem/24945 ๐ง ๊ด์ฐฐ ๋ฐ ์ ๊ทผ # ์๋ธํ์คํฌ๊ฐ ์๋นํ ๋ง๊ณ , ๋ฌธ์ ๊ฐ ์ฝ์ง ์์๋ณด์ธ๋ค. ์ฐจ๊ทผ์ฐจ๊ทผ ํด๋ณด์. $N = 3$ ๋ธ๋ฃจํธํฌ์ค์ ๊ฐ๊น๊ฒ ํ ์ ์์ ๊ฒ ๊ฐ๋ค. ๋ฌธ์๋ ์ด์ฐจํผ ์ต๋ 3๊ฐ ์กด์ฌํ๋ฏ๋ก, 3๊ฐ์ ๋ํด $X$๊ฐ ๊ฐ์ง ์ ์๋ ๊ฒฝ์ฐ์ ์ $3^3$๊ฐ์ง, $Y$๊ฐ ๊ฐ์ง ์ ์๋ ๊ฒฝ์ฐ $3^3$๊ฐ์ง๋ฅผ ์ ์ดํ๋ฉด์ ๋ค์ต์คํธ๋ผ๋ก ํ ์ ์์ ๊ฒ ๊ฐ๋ค. ใ
ใ
๋๋น $S_i = a$ ๋ชจ๋ ๋ฌธ์๊ฐ a๋ผ๋ฉด? $X$์ ๋ค์ด์๋ ๋ฌธ์ ๊ฐ์, $Y$์ ๋ค์ด์๋ ๋ฌธ์ ๊ฐ์ ๋๊ฐ์ง๋ฅผ ์ด์ฉํด์ $N^2$ ์ ์ ๋ค์ต์คํธ๋ผ๊ฐ ๊ฐ๋ฅํด๋ณด์ธ๋ค. $N \leq 30$ ์ด์ ๋ถํฐ ์ง์ง๋ก ์ด๋ป๊ฒํ์ด์ผํ๋์ง ๊ณ ๋ฏผํด๋ด์ผํ ๊ฒ ๊ฐ์๋ฐ… ์ผ๋จ ๋ณต์ฌํ ๋ฌธ์ $Y$๋ $X$์ substr์ด์ด์ผํ ๊ฒ์ด๋ค. ๊ทธ๋ผ $Y$๊ฐ ๋ ์ ์๋ ๊ฒฝ์ฐ์์๋ $O(N^2)$์ด๊ณ $X$๋ฅผ ๋ง๋ค๋๋ , $Y$๋ฅผ ๋ง๋ค๊ธฐ์ํด ๋น๋์
ํ๊ณ ์์๋๋ ๊ฒฐ๊ตญ $X$๋ $X$์ substr๋ก ์กด์ฌํด์ผํ๋ค. ์ด๊ฒ๋ ๊ฒฝ์ฐ์์๊ฐ $O(N^2)$ ์ธ ๊ฒ ๊ฐ๋ค. $Y$๋ฅผ ๋ถ์ผ ์ ์๋์ง ๊ฒ์ฌํ๋? ๊ทธ๋ฐ๊ฒ๋ค์ด ์ ์ฒ๋ฆฌ๋ฅผ ์ํ๋ฉด $O(N)$์ฏค ๋์ด๋ณด์ด๋, ์๋ง ์ข
ํฉํด์ $O(N^5)$์ ๋๋ก ํ ์ ์์ง ์๋? ๊ทผ๋ฐ DP ์ ์ด์์ด ํท๊ฐ๋ฆฐ๋ค. ์ด๊ฒ ์ํธ ์ฐธ์กฐ๊ฐ ์๋? ๋น์ฉ๋ค์ด ๋ฌ๋ผ์ ๋ค์ต์ผ๋ก ํด์ผ๋ ๊ฒ ๊ฐ์๋ฐ. $\text{DP}[x][y]$: ํ์ฌ $X$์ $x$, $Y$์ $y$๊ฐ ๋ค์ด์๋ค๊ณ ํ์. $A$ ์ฐ์ฐ์ ๊ฑฐ์น๋ฉด $x$์ ํ๊ฐ๊ฐ ๋ถ๊ณ , $y$๋ ๊ทธ๋๋ก๋ค. $B$ ์ฐ์ฐ์ ๊ฑฐ์น๋ฉด $x$๊ฐ ๋น ๋ฌธ์์ด์ด ๋๊ณ , $y$๋ $x$์ ๊ฐ์ผ๋ก ๊ฐฑ์ ๋๋ค. $C$์ฐ์ฐ์ ๊ฑฐ์น๋ฉด $x = x + y$๊ฐ ๋๊ณ , $y$๋ ๊ทธ๋๋ก๋ค. ์ํ, ์๊ฐ๋ณด๋ค $y$๊ฐ ๊ฐฑ์ ๋ ์ผ์ด ์๋ค. ๊ทธ๋ฆฌ๊ณ $y$๊ฐ ๊ฐฑ์ ๋๋ค๋ฉด $x$๊ฐ ๋น ๋ฌธ์์ด์ด ๋ ์ํ์์ ์์ํ๋ค! ๋ณต์ฌํ๊ณ ๋ถ์ฌ๋ฃ๋ ๊ณผ์ ์ ๊ทธ๋ฅ ํด๋ฒ๋ ธ๋ค๊ณ ์๊ฐํ๋๊ฒ ๋ ์ฌ์ธ ๊ฒ ๊ฐ๋ค. $\text{DP}[i][j]$ : $S_i$~$S_j$๊น์ง ๋ง๋๋ ์ต์๋น์ฉ์ด๋ผ๊ณ ํ์. ์ด๊ฑด $\text{DP}[i][j-1]$ ํ $A$์ฐ์ฐ์ ํ๊ฑฐ๋ ์ด๋ค $i \leq i', j' \leq j$๊ฐ ์์ด์ ๊ทธ์น๊ตฌ๋ฅผ ๋ณต์ฌํ ํ ๋ถ์ฌ๋ฃ๊ธฐ๋ฅผ ์ฌ๋ฌ๋ฒ ํ๊ฑฐ๋. ์ด๊ฑด ๊ทธ๋ฆฌ๋ํ๊ฒ ๋๋๋ฏ? ํ๋ฒ ์ง๋ณด์. ์ค!!! ์ด๊ฑธ๋ก ๋์ถฉ $30^5$์ ๋๋ ์ฑ๊ณตํ๋ค! $N \leq 200$ ์ด์ $O(N^4)$๋ 16์ต์ด๋ ๋นก์ธ๊ณ , $O(N^3\log{N})$์ฏค ๊น์ง๋ ์ค์ฌ์ผํ๋๋ฐ… ์ญํ 5๋ ์ธ์ ๊ณฑ, ์ญํ 6์ ์ ๊ณฑ๋ก๊ทธ๊ฒ ๋ค. ์, ์์์ ํ๋ ๊ด์ฐฐ๋๋ก $Y$์ ๋ณต์ฌํด์ ๋ฃ์ผ๋ฉด $X$๋ ์ด๊ธฐํ๋ผ์ ์์ํ๋ฏ๋ก, DP๋ฅผ $B$์ฐ์ฐ์ผ๋ก $Y$์ ๋ณต์ฌํ๊ฑฐ๊น์ง ํ์ ๋๋ฅผ ๊ธฐ์ค์ผ๋ก ํ์. ์ ค ์ค์ํ๊ฑฐ๋ ์ ๊ทธ๋ฆฌ๋ํ๊ฒ ๋น๊ตํ๋ฉด์ ๋ค๋ก ์์์ ๊ฐ๋ ํํธ์ธ ๊ฒ ๊ฐ๋ค. ๐ป ํ์ด # ์ฝ๋ (C++): void solve(){ cin >> N >> S >> A >> B >> C; if(N >= mxN) { cout << -1 << "\n"; return; } rep(i, 0, N+1) rep(j, 0, N+1) DP[i][j] = LLONG_MAX; rep(i, 0, N+1) rep(j, i+1, N+1) DP[i][j] = A * (j-i) + B; const mint base = 131; const mint2 base2 = 137; vector<mint> hsh(N+1), pw(N+1); vector<mint2> hsh2(N+1), pw2(N+1); hsh[0] = 0; pw[0] = 1; hsh2[0] = 0; pw2[0] = 1; rep(i, 0, N){ hsh[i+1] = hsh[i] * base + S[i]; pw[i+1] = pw[i] * base; hsh2[i+1] = hsh2[i] * base2 + S[i]; pw2[i+1] = pw2[i] * base2; } auto getHash = [&](int l, int r) -> pair<ll, ll>{ ll ret1 = (hsh[r] - hsh[l] * pw[r-l]).get(); ll ret2 = (hsh2[r] - hsh2[l] * pw2[r-l]).get(); return {ret1, ret2}; }; ll ans = N*A; rep(L, 1, N+1){ // A ์ฐ์ฐ ์๋ค์ ๋ถ์ฌ์ ์ ์ดํ ๋ if(L >= 2) rep(s, 0, N){ if(s+L > N) break; int e = s+L; DP[s][e] = min(DP[s][e], DP[s+1][e]+A); DP[s][e] = min(DP[s][e], DP[s][e-1]+A); } // ํด๋น ๋ฌธ์์ด์ ๋ณต์ฌํ๋ ์ต์ ๋น์ฉ map<pair<ll,ll>, vector<int>> mp; rep(s, 0, N){ if(s+L > N) break; int e = s+L; mp[getHash(s, e)].push_back(s); } // ๋ณต์ฌ ์ฐ์ฐ์ผ๋ก ์ ์ด for(auto& [_, v]: mp){ int sz = v.size(); ll mn = 1e18; for(auto s: v) mn = min(mn, DP[s][s+L]); // ๋ค์์ ๊ฐ ์ ์๋ ์์น vector<int> nxt(sz, sz); for(int i = 0, j = 0; i < sz; i++){ while(j < sz && v[j] < v[i]+L) j++; nxt[i] = j; } rep(i, 0, sz){ int s_pos = v[i]; int cidx = i; int cnt = 0; while(cidx < sz){ cnt++; int e_pos = v[cidx]+L; if(e_pos > N) break; DP[s_pos][e_pos] = min(DP[s_pos][e_pos], mn + (C * cnt) + ((e_pos - s_pos) - (L * cnt)) * A + B); cidx = nxt[cidx]; } } } } ans = min(ans, DP[0][N] - B); cout << ans << "\n"; } ๐ ๊ตฌํ ์ฝ๋ ์ ๊ธ