Skip to main content

Hashing

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"; } ๐Ÿ”’ ๊ตฌํ˜„ ์ฝ”๋“œ ์ž ๊ธˆ