AOJ solutions
this repo has solutions of some problems at AOJ(algospot.com)
contact : won.seok.django@gmail.com
##์ ๋ต
- ๋น์ทํ ๋ฌธ์ ๋ ์ฌ๋ฆฌ๊ธฐ.
- brute force.
- ์์๋ฅผ ๊ฐ์ ํ๊ธฐ.
- ๋ค์์๋ถํฐ ํ์ด๋ณด๊ธฐ.
- ๋ถํดํ๊ธฐ/๊ทธ๋ฃน์ง๊ธฐ.
- ์์ผ๋ก ํ์ด๋ณด๊ธฐ.
- ๊ทธ๋ฆผ ๊ทธ๋ ค๋ณด๊ธฐ.
- ์์์ผ๋ก ํ์ด๋ณด๊ธฐ.
###๋ฌธ์ ID : FESTIVAL(AOJ_FESTIVAL.cpp)
2016.12.28.(์)
๋งค์ฐ ์ฌ์ด ๋ฌธ์ ์ ์ํ๋ค. ์ ์ฒด N์ผ ์ค L๊ฐ ์ด์ ์ฐ์ํ ๊ตฌ๊ฐ์ ๋ชจ๋ ๊ฒ์ฌํ์ฌ ์ต์์ ํ๊ท ๋์ฌ์ผ์ ๊ฐ๋ ๊ตฌ๊ฐ์ ์ฐพ์ผ๋ฉด ๋๋ค. N์ ๋ฒ์๊ฐ 1000๊ฐ ๋ฐ์ ๋์ง ์์ผ๋ฏ๋ก ๊ฐ๋ฅํ ๊ฒฝ์ฐ์ ์๋ ์๋ฌด๋ฆฌ ๋ง์ 1000H2๊ฐ ๋ฟ์ด๊ณ ์ด๋ ์ถฉ๋ถํ 1์ด์์ ํ ์ ์๋ ์ ๋ ฅ์ ํฌ๊ธฐ์ด๋ค. ๊ตฌ๊ฐ์ ํ๊ท ์ ๊ตฌํ๋ ๊ณผ์ ์์ ์ด๋ ํ๊ท ์์ด๋์ด๋ฅผ ์ฌ์ฉํ๋ฉด ๋ณด๋ค ๋์ ํจ์จ์ ๋ณด์ผ ์ ์๋ค.
double solve(void)
{
int sum = 0;
double avg = MAXAVG;
for (int s = 0; s <= N - L; ++s)
{
// initial min avg from s to s + L - 1.
sum = 0;
for (int l = 0; l < L; ++l)
{
sum += COST[s + l];
}
avg = std::min(avg, (double)sum / L);
// min avg from s to e.
for (int e = s + L; e < N; ++e)
{
sum += COST[e];
avg = std::min(avg, (double)sum / (e - s + 1));
}
}
return avg;
}
###๋ฌธ์ ID : PICNIC(AOJ_PICNIC.cpp)
2016.12.30.(๊ธ)
์ ๋ ฅ์ ํฌ๊ธฐ๊ฐ 10์ผ๋ก ๋งค์ฐ ์์ ํธ์ด์ด์ brute force ๋ฐฉ๋ฒ์ผ๋ก ๋ชจ๋ ๊ฒฝ์ฐ์ ์๋ฅผ ์ธ์ด์ฃผ๋ฉด ๋๋ค. ์ต์ ์ ๊ฒฝ์ฐ(๋ชจ๋๊ฐ ์น๊ตฌ์ธ ๊ฒฝ์ฐ)์๋ 10C2 * 8C2 * 6C2 * 4C2 * 2C2 / 5! - 945๊ฐ์ ์กฐํฉ๋ง์ด ์กด์ฌํ๋ฏ๋ก ์ถฉ๋ถํ ์ฃผ์ด์ง ์๊ฐ ๋ด์ ํ ์ ์๋ค. ๋ค๋ง, ๋ชจ๋ ์กฐํฉ์ ํ์ํ๋ ํจ์์ ๊ตฌํ์ด ์ฒ์์๋ ์กฐ๊ธ ์ด์ํ๊ฒ ๋๊ปด์ก์๋๋ฐ ๊ตฌํ ํด๋๊ณ ๋ณด๋ ์ ๋์ํ์๊ณ ์ฑ ์ ๊ตฌํ๊ณผ๋ ๊ฑฐ์ ์ผ์นํ์๋ค. ์ฌ๊ท์ ์ผ๋ก ์ํ๋๋ ํจ์ solve๋ ์๋์ ๊ฐ์ด ๋์ํ๋ค.
/**
* ๋ชจ๋ ํ์์ด ์ง์ ๊ฐ์ง๊ฒ ๋ ๊ฒฝ์ฐ 1์ ๋ฐํํ๊ณ , ๋ถ๊ฐ๋ฅํ ์กฐํฉ์ ๊ฒฝ์ฐ 0์ ๋ฐํํ๋ค.
* ์ง์ ๊ฐ์ง์ง ์์ ์ฌ์ ์์ผ๋ก ๊ฐ์ฅ ์์ ํ์์ ์ฐพ๊ณ , ์ญ์ ์ฌ์ ์์ผ๋ก ์ง์ ๋ฐฐ์ ํ๋ค.
* ์ฌ๊ท์ ์ผ๋ก ๋ฐ๋ณตํ์ฌ ๋ชจ๋ ๊ฐ๋ฅํ ์กฐํฉ์ ์๋ฅผ ์ผ๋ค.
*/
int solve(void)
{
int idx;
for (idx = 0; idx < N && IS_PAIRED[idx]; ++idx);
if (idx == N) ///< ๋ชจ๋ ํ์์ด ์ง์ ์ฐพ์ ๊ฒฝ์ฐ 1์ ๋ฐํ.
return 1;
int ret = 0; ///< ๋ถ๊ฐ๋ฅํ ์กฐํฉ์ธ ๊ฒฝ์ฐ์๋ 0์ ๋ฐํ.
for (int l = 0; l < N; ++l)
{
if (!IS_PAIRED[l] && IS_FRIEND[idx][l])
{
IS_PAIRED[idx] = IS_PAIRED[l] = true; ///< ์ ํ์ ๋ฐ์.
ret += solve(); ///< ์กฐํฉ์ ๊ฐฏ์๋ฅผ ์ผ๋ค.
IS_PAIRED[idx] = IS_PAIRED[l] = false; ///< ์ ํ ๋ฐ์์ ์ทจ์.
}
}
return ret;
}
###๋ฌธ์ ID : BOARDCOVER(AOJ_BOARDCOVER.cpp)
2017.01.04.(์)
์ฒ์์ ๋ฌธ์ ๋ฅผ ํธ๋ ๋ฐฉํฅ์ ์๋ชป ์ก์์ ๊ณ ์์ ํ๋ค. ๋งจ ์ฒ์์ ์ ๊ทผ์ ๋ค์๊ณผ ๊ฐ์๋ค.
-
๋งค ์ฌ๊ท ํธ์ถ๋ง๋ค ๋ณด๋์์ row-major๋ก ๊ฐ์ฅ ์ฒ์์ ๋น ์นธ์ ์ฐพ๋๋ค.
-
๋น ์นธ์ด ์๋ค๋ฉด ๋ณด๋ ๋ฎ๊ธฐ์ ์ฑ๊ณตํ ๊ฒฝ์ฐ์ด๋ค.
-
๋น ์นธ์ ๋ํ์ฌ ๋ค์์ 5๊ฐ์ง ๊ฒฝ์ฐ์ ๋ํ์ฌ ์ -ํ์ ํด๋ณธ๋ค.
a. ํด๋น ์นธ์ ํ์ธํ์์๋ง ํ์ํ๊ณ ์๋ฌด ๋ธ๋ก๋ ๋ฐฐ์นํ์ง ์๋๋ค(๋ค์ ๋ฒ์ ์ฌ๊ท ํธ์ถ์์ ์ฑ์์ง๋๋ก ๋น์นธ์ผ๋ก ์ ์ง). b. ํด๋น ์นธ์ ์๋์ 4๊ฐ์ง ๊ฒฝ์ฐ์ ๋ธ๋ก์ผ๋ก ๋ฐฐ์นํด๋ณธ๋ค.
์ด ๋ฐฉ๋ฒ์ ๊ฐ ๋น ์นธ์ ๋ํ์ฌ 5๊ฐ์ง ๊ฒฝ์ฐ์ ์๋ฅผ ๊ณ ๋ คํ๊ฒ ๋๊ณ ์ด๋ roughํ๊ฒ 5^50๊ฐ์ ๊ฒฝ์ฐ์ ์๋ฅผ ์ธ๊ฒ ๋๋ค. ์ด๋ 2์ด ์ ํ์ ํ๊ธฐ์๋ ํฐ ๊ฒฝ์ฐ์ ์์ด๋ฏ๋ก ๋ต์ ๊ตฌํ ์๋ ์์ง๋ง TLE๋ฅผ ๊ฒช๊ฒ ๋๋ค.
๋ค์์ผ๋ก ์๋ํ ๋ฐฉ๋ฒ์ ์ฒ์ ์ ๊ทผํ ๋ฐฉ๋ฒ์ธ brute force๋ฅผ ์ ์งํ๋ ์์๋ฅผ ๊ฐ์ ํ ์ํจ ๋ฐฉ๋ฒ์ด๋ค. ๋งค ์ฌ๊ท ํธ์ถ๋ง๋ค row-major๋ก ๊ฐ์ฅ ์ฒ์์ ๋น ์นธ์ ์ฐพ์ผ๋ฏ๋ก row-major๋ก ํด๋น ๋น ์นธ ์ด์ ์ ์์นํ๋ ๋น ์นธ๋ค์ ์ด๋ฏธ ๋ชจ๋ ์ฑ์์ง ํํ๋ก ๊ฐ์ ํ๋ ๊ฒ์ด ๋ฐฉ๋ฒ์ ํต์ฌ์ด๋ค.
-
๋งค ์ฌ๊ท ํธ์ถ๋ง๋ค ๋ณด๋์์ row-major๋ก ๊ฐ์ฅ ์ฒ์์ ๋น ์นธ์ ์ฐพ๋๋ค.
-
๋น ์นธ์ด ์๋ค๋ฉด ๋ณด๋ ๋ฎ๊ธฐ์ ์ฑ๊ณตํ ๊ฒฝ์ฐ์ด๋ค.
-
๋น ์นธ์ ๋ํ์ฌ ์๋์ ๊ฒฝ์ฐ๋ฅผ ๊ณ ๋ คํ๋ค.
์ค์ ๋ก row-major๋ก ํด๋น ๋น์นธ ์ด์ ์ ๋ธ๋ก์ด ๋ชจ๋ ์ฑ์์ ธ ์๋ค๊ณ ๊ฐ์ ํ๋ค๋ฉด ๊ณ ๋ ค์ ๋์์ด ๋๋ ๋ธ๋ก์ 2, 5, 9, 12๋ฒ์งธ ๋ธ๋ก ๋ฟ์ด๋ค. ๋ฐ๋ผ์, ์์ 4๊ฐ ๋ธ๋ก์ ๋ํ์ฌ ์ -ํ์์ ์ํํ๋ฉด ๊ฒฝ์ฐ์ ์๊ฐ 4^(floor(50/3))์ด ๋๊ฒ ๋๋ค. ์ด ์ญ์ 2์ด ์ ํ์ ํ๋ฆฌ๊ธฐ๋ ์ด๋ ค์ด ์ ๋์ ๊ฒฝ์ฐ์ ์์ธ๋ฐ ์ค์ ๋ก ๊ตฌํํด๋ณด๊ฒ ๋๋ฉด n-th ์ฌ๊ท๋จ๊ณ์์ ๋์ ๋ธ๋ก์ ํํ์ ๋ฐ๋ผ n+1-th ์ฌ๊ท๋จ๊ณ์์ ๋๊ฒ ๋๋ ๋ธ๋ก์ด ํฌ๊ฒ ์ ํ๋๋ฏ๋ก prunning์ด ์ปค์ง๊ฒ ๋๋ค. ์๋ฅผ ๋ค์ด 2*3 ํฌ๊ธฐ์ ๋ณด๋๋ฅผ ๋ฎ๊ธฐ ์ํด์๋ ์ด๋ก ์ ์ผ๋ก 4^2๊ฐ์ ๊ฒฝ์ฐ์ ์๋ฅผ ๊ณ ๋ คํด์ผํ์ง๋ง ์ค์ ๋ก๋ 12๊ฐ ๋ฐ์ ๊ณ ๋ คํ์ง ์๋๋ค. ์ด๋ ๊ฒ ๋ฌธ์ ๋ฅผ ๋ถ์ํด๋ณด๊ณ ์ด๋ก ๊ณผ ๊ตฌํ์ ์ํ์๊ฐ์ด ๋ค๋ฅด๋ค๋ ๊ฒ์ ์ฌ์ ์ ํ์ ํ ์ ์๋ ๊ฒ์ด ์ค์ํ๋ฐ, ๊ณผ์ฐ ์ค์ ๋ก ๋ฌธ์ ๋ฅผ ํ ๋ ์ด๋ฐ ๋ถ๋ถ๋ค์ ์ ๋์ฒํ ์ ์๋์ง์ ๋ํ ์์ ์ด ์๋ค.
int solve(void)
{
int r, c;
for (r = 0; r < H; ++r)
{
for (c = 0; c < W; ++c)
{
if (BOARD[r][c] == '.')
break;
}
if (c != W)
break;
}
if (r == H && c == W)
return 1;
int ret = 0;
for (int blk = 0; blk < NUMOFBLOCKS; ++blk)
{
int idx;
for (idx = 0; idx < NUMOFBLANKS; ++idx)
{
if (
!safe(r + dr[blk][idx], c + dc[blk][idx]) ||
BOARD[r + dr[blk][idx]][c + dc[blk][idx]] != '.')
break;
}
// you can put blk-th block.
if (idx == NUMOFBLANKS)
{
for (idx = 0; idx < NUMOFBLANKS; ++idx)
BOARD[r + dr[blk][idx]][c + dc[blk][idx]] = '#';
ret += solve();
for (idx = 0; idx < NUMOFBLANKS; ++idx)
BOARD[r + dr[blk][idx]][c + dc[blk][idx]] = '.';
}
}
return ret;
}
###๋ฌธ์ ID : CLOCKSYNC(AOJ_CLOCKSYNC.cpp)
2017.01.06.(๊ธ).
์ง์ ๋ชจ๋ ๊ฒฝ์ฐ๋ฅผ ์ -ํ์ํ๋ ๋ฐฉ๋ฒ์ผ๋ก ํ์ด๋ผ ์ ์๋ ๋ฌธ์ ์ด๋ค. ์ ํ์์ ์ ์ฉํ๊ธฐ ์ํด์๋ ์๋์ ๊ฐ์ ๋ ๊ฐ์ง ์ฌ์ค์ ๊นจ๋ซ๋ ๊ฒ์ด ์ค์ํ๋ค.
1. ๋ฒํผ์ ๋๋ฅด๋ ์์๋ ๋ต์ ์ํฅ์ ์ฃผ์ง ๋ชปํ๋ค.
2. ๋ฒํผ์ 4ํ ์ด์ ๋๋ฅด๋ ๊ฒ์ ๋ง๋ฌด๋ฐ ์๋ฏธ๊ฐ ์๋ค.
๋ฐ๋ผ์, ๋ฒํผ์ ๋๋ฅด๋ ์์๋ฅผ 0๋ฒ9๋ฒ์ผ๋ก ๊ฐ์ ํํ๊ณ , ๊ฐ ๋ฒํผ์ ํด๋ฆญ์ 0ํ3ํ๋กํ์ฌ ์ -ํ์์ํ๊ฒ ๋๋ฉด ์ด 4^10๊ฐ์ ๊ฒฝ์ฐ์ ์๋ฐ์ ํ์ํ๊ฒ ๋๋ค. ์ด๋ ์ ํ์๊ฐ ๋ด์ ์ถฉ๋ถํ ๋ฌธ์ ๋ฅผ ํ์ด๋ผ ์ ์๋ค. ํํธ, ์ฌ๊ทํจ์์ ๊ฒฝ์ฐ (์ด๋ฒ์ ๊ณ ๋ คํ ๋ฒํผ์ ๋ฒํธ, ํ์ฌ๊น์ง ๋ฒํผ์ ํด๋ฆญ ํ์) ๋ฅผ ์ธ์๋ก ๋ฐ์ ๊ณ ๋ คํ ๊ฐ์น๊ฐ ์๋ ๋ต์ ํ๋ณด๋ ์ ์ ํ prunningํ๋ค.
void solve(int btn, int cnt)
{
int clk;
for (clk = 0; clk < NUMOFCLOCKS && CLOCKS[clk] == 0; ++clk);
if (clk == NUMOFCLOCKS)
{
CNT = (CNT > cnt) ? cnt : CNT;
return;
}
if (btn == NUMOFBUTTONS)
return;
// click btn-th button.
int idx;
for (int click = 0; click < 4 && cnt + click < CNT; ++click)
{
idx = 0;
while (TRIGGER[btn][idx] != -1)
{
CLOCKS[TRIGGER[btn][idx]] = (CLOCKS[TRIGGER[btn][idx]] + 3 * click) % 12;
++idx;
}
solve(btn + 1, cnt + click);
idx = 0;
while (TRIGGER[btn][idx] != -1)
{
CLOCKS[TRIGGER[btn][idx]] = (CLOCKS[TRIGGER[btn][idx]] + 9 * click) % 12;
++idx;
}
}
}
###๋ฌธ์ ID : QUADTREE(AOJ_QUADTREE.cpp)
2016.01.06.(๊ธ).
์ง์ ์์ผ๋ก ๋ฌธ์ ๋ฅผ ํ์ด๋ณด๊ฒ ๋๋ฉด ์์ฐ์ค๋ TREE๋ฅผ ๊ทธ๋ฆฌ๊ฒ ๋๋ค(์ด์ฉ๋ฉด ๋ฌธ์ ์ด๋ฆ ์์ฒด๊ฐ TREE์ด๋ ๋น์ฐํ ๊ฒ์ผ ์๋ ์๊ฒ ๋ค). ๋ช ๋ฒ ํ์ด๋ณด๋ฉด TREE์ leaf node๋ถํฐ ์ํ๋ฅผ ๋ฐ์ ์์ผ์ฃผ๋ฉด ๋๋ ๊ฒ์ ์ ์ ์๊ณ ์ฌ๊ทํจ์๋ฅผ ์ฌ์ฉํ๋ฉด ๋ ๊ฒ ๊ฐ์ ๊ฐํ ๋๋์ ๋ฐ์ ์ ์๋ค. ์ด๋, ์ค์ ๋ก TREE๋ฅผ ๊ตฌ์ฑํ๊ณ ์ฌ๊ท์ ์ผ๋ก ์ํ๋ฅผ ๋ฐ์ ์ํฌ์ง ๊ทธ๋ฅ ๋ฌธ์์ด์ ์ฝ์ผ๋ฉด์ ์ฒ๋ฆฌํ ์ง ๊ณ ๋ฏผํ๋๋ฐ ์๋ฌด๋๋ ๋ ๋ฒ์งธ ํ๋ค๋ณด๋ TREE๋ฅผ ์ง์ ๊ตฌ์ฑํ์ง ์๊ณ ๋ ์ถฉ๋ถํ ํ ์ ์๋ค๋ ๊ฒ์ด ๋ ์ฌ๋๋ ๊ฒ ๊ฐ๋ค. ์ฌ๊ทํจ์๋ก ๋ฌธ์ ๋ฅผ ํ๊ธฐ๋ก ๊ฒฐ์ฌํ์ผ๋ ์ฌ๊ทํจ์์ return ๊ฐ๊ณผ parameter๋ฅผ ๋ฌด์์ผ๋ก ํ ์ง, base case๋ ๋ฌด์์ธ์ง, recursive step์ ๋ฌด์์ธ์ง ๊ฒฐ์ ํด์ฃผ๋ฉด ๋๋ค. ๊ฐ๊ฐ์ ์๋์ ๊ฐ์ด ๊ฒฐ์ ํ์๋ค.
- ๋ฐํ ๊ฐ
๊ฒฐ๊ตญ ํ๋ก๊ทธ๋จ์์ ์ํ๊ฐ ๋ฐ์ ๋ QUADTREE ๋ฌธ์์ด์ ๋ฐํํด์ค์ผํ๋๋ฐ ์ด ๋ฌธ์์ด์ ์ฌ๊ทํจ์ ๋ด์์ ํ๋์ ์ ์ญ ๋ฌธ์์ด ๋ฒํผ์ ์ฐ๊ธฐ๋ก ๊ฒฐ์ ํ๋ฉด ์ ์ญ ๋ฒํผ์ ์ฐ์ธ ๋ฌธ์์ด์ ์์๋ฅผ ์ฌ๋ฐฐ์น ํด์ฃผ์ด์ผํ๋ ๋ฑ ๊ท์ฐฎ์์ง๋ค. ์ด๋ฐ ๊ฒฝ์ฐ ๋ฐํ ๊ฐ์ ์ฌ๊ทํจ์์ ๋ฐํ ๊ฐ์ผ๋ก ํด์ฃผ๋ฉด ๋ณด๋ค ์ฌ์ด ์ฝ๋ฉ์ด ๊ฐ๋ฅํ๋ค. ๋ฐ๋ผ์, ์ฌ๊ทํจ์๋ ํ์ฌ ์์น๋ก๋ถํฐ sub-tree๋ฅผ ์ํ๋ฐ์ ์ํจ QUADTREE๋ฌธ์์ด์ ๋ฐํํ๋ค.
- ์ธ์
์ ๋ ฅ ๋ฌธ์์ด์์ ์ด๋๊น์ง ์ฝ์๋์ง๋ฅผ ์ ์ ์์ด์ผ ์ฌ๊ทํจ์์ ๊ฐ ๋จ๊ณ์์ ์ด๋์๋ถํฐ QUADTREE ๋ณํ์ ์์ํ ์ง๋ฅผ ๊ฒฐ์ ํ ์ ์๋ค. ๋ฐ๋ผ์, ์ฌ๊ทํจ์์ ์ธ์๋ก '์ด๋ฒ์ ์ฝ์ ์ ๋ ฅ ๋ฌธ์์ด ์์น'๋ฅผ ์ค๋ค. CLOCKSYNC์์ ์ฌ๊ทํจ์๊ฐ cnt๋ฅผ ์ธ์๋ก ๊ฐ์ก๋ ๊ฒ๊ณผ ์ ์ฌํ๊ฒ ์ฌ๊ท์ ์ผ๋ก ์ ์ง๋์ด์ผ ํ ๊ฐ๋ค์ ๊ฒฝ์ฐ ์ธ์๋ก ์ค์ ํ๋ฉด ํธ๋ฆฌํ๋ค.
- base case
base case๋ ๋น์ฐํ 'b', 'w'์ ๊ฐ์ด ํ ์์ ํ์ผ๋ก ์ด๋ค์ง ๊ฒฝ์ฐ์ด๋ค. ์ฆ, ์ด๋ฒ์ ์ฝ์ ์ ๋ ฅ ๋ฌธ์์ด ์์น์ 'b' ๋๋ 'w'๊ฐ ์ฐ์ฌ ์๋ค๋ฉด ๊ณง์ฅ ๋ฌธ์์ด "b" ๋๋ "w"๋ฅผ ๋ฐํํ๋ค.
- recursive step
์ด๋ฒ์ ์ฝ์ ์ ๋ ฅ ๋ฌธ์์ด ์์น์ 'x'๊ฐ ์ฐ์ฌ ์๋ค๋ฉด ์ฌ๊ท์ ์ผ๋ก sub-tree๋ฅผ ์ํ๋ฐ์ ์์ผ์ค์ผ ํจ์ ์๋ฏธํ๋ค. ์ด ๊ฒฝ์ฐ, ์์๋๋ก upper-left, upper-right, lower-left, lower-right๋ฅผ ์ฌ๊ท์ ์ผ๋ก ๋ค์ง์ด์ฃผ๊ณ , lower-left, lower-right, upper-left, upper-right ์์ผ๋ก sub-tree์ ์์๋ฅผ ๋ค์ง์ด ๋ฐํํด์ค๋ค.
base case์ recursive step์ ์ ํ๋ ๊ฒ ๋ง์ผ๋ก ๋ฌธ์ ๊ฐ ํ๋ฆฐ๋ค๋ ๊ฒ์ ์ง๊ด์ ์ผ๋ก ์ ์ ์๋ค. ์ด์ ๋ฌธ์ ๊ฐ ์ค์ ๋ก ์ ํ์๊ฐ ๋ด์ ํ๋ฆด์ง ๊ณ ๋ คํด๋ด์ผ ํ๋ค. ๋์ฒด, ์, ์ด์งธ์ ํ๋ถ๋๋ถํฐ ํญ์ ๊น๋จน๋์ง ์ดํดํ ์ ์๋ master theorem์ด ์ฌ์ฉ๋๋ค.
T(n) = 4 * T(n/4) + n ์ด๋ฏ๋ก T(n) = nlgn์ด๊ณ , ์ด๋ ์ ํ ์๊ฐ์ ๋ฌธ์ ๋ฅผ ์ถฉ๋ถํ ํ ์ ์์์ ๋ณด์ฌ์ค๋ค.
string solve(int pos)
{
// base case.
if (QUADTREE[pos] != 'x')
{
return QUADTREE.substr(pos, 1);
}
// recursive step.
string ul, ur, ll, lr;
ul = solve(pos + 1);
ur = solve(pos + 1 + ul.size());
ll = solve(pos + 1 + ul.size() + ur.size());
lr = solve(pos + 1 + ul.size() + ur.size() + ll.size());
return "x" + ll + lr + ul + ur;
}
###๋ฌธ์ ID : FENCE(AOJ_FENCE.cpp)
2017.01.07.(ํ ).
์์ธ๋ก 2๋ฒ์ด๋ ์ค๋ต์ ๋๋ค. ์ฒซ ๋ฒ์งธ๋ ํ์ฌ ์ฌ์ฉ ์ค์ธ IDE์์ ์ฝ์ ๋ณต์ฌ ๋ถ์ฌ๋ฃ๊ธฐ๋ฅผ ์ง์ํ์ง ์๊ธฐ์ freopen(*)์ ์ฌ์ฉํ์๋๋ฐ submitํ ๋ ์ด๋ฅผ ์์ ํ์ง ์๊ณ ๊ทธ๋๋ก ์ ์ถํด์ ์ค๋ต์ ๊ฒช์๋ค. #ifdef ๊ตฌ๋ฌธ ๋ฑ์ ํ์ฉํด์ ์์ผ๋ก ๋น์ทํ ์ค์๋ฅผ ๋ฐฉ์งํ๋ ๊ฒ์ด ์ข์ ๊ฒ ๊ฐ๋ค. ๋ ๋ฒ์งธ ์ค๋ต์ ๊ตฌ๊ฐ์ ๋ํ ๋ถํ ์ ๋ณต ์๊ณ ๋ฆฌ์ฆ์ ์ฌ์ฉํ๋ ๋จ๊ณ์์ s, e(๋๋ lo, hi)์ indexing ์ค์๋ก ์ธํด ๋ฐ์ํ๋ค. ํญ์ ๋น์ทํ ๋ฌธ์ ๋ฅผ ํ ๋ indexing์ ์ค์ํ๋ ๊ฒฝ์ฐ๊ฐ ์๋๋ฐ ์ด ์ญ์ ์ง์ ๋ช๋ช case๋ฅผ ์์ผ๋ก ํ์ด๋ณด๋ ๋ฐฉ๋ฒ์ผ๋ก ๊ทน๋ณตํ๋ ๋ ธ๋ ฅ์ด ํ์ํ ๊ฒ์ผ๋ก ๋ณด์ธ๋ค.
์ด ๋ฌธ์ ๋ ๋ถํ ์ ๋ณต ์์ด๋์ด๋ฅผ ์ฌ์ฉํด์ ํ ์ ์๋ค. ๋ฌธ์ ๊ฐ ๋ถํ ์ ๋ณต ๋จ์์ ์๋ก๋์ด์ ๋ ์ฌ๋ฆด ์ ์์๋ ๊ฑด์ง, ์ค์ ๋ก ๋ถํ ์ ๋ณต์ด ๋ ์ค๋ฅด๋ ๋ฌธ์ ํ์์ด์ด์ ๊ทธ๋ฌ๋ ๊ฒ์ธ์ง๋ ์ค์ค๋ก ๋งค์ฐ ์์ฌ์ค๋ฝ์ง๋ง ์ฐ์ ํ๊ธฐ๋ก ํ๋ค. ์ต๋์ ๋์ด๋ฅผ ๊ฐ๋ ์ง์ฌ๊ฐํ์ ์๋์ 3๊ฐ์ง ๊ฒฝ์ฐ ์ค ํ๋์ ๋ฐ๋์ ์ํ๋ค.
- [s, m) ๊ตฌ๊ฐ์ fence๋ฅผ ์ฌ์ฉํด์ ๋ง๋ค์ด์ง๋ ๊ฒฝ์ฐ.
- (m, e] ๊ตฌ๊ฐ์ fence๋ฅผ ์ฌ์ฉํด์ ๋ง๋ค์ด์ง๋ ๊ฒฝ์ฐ.
- m์ ํฌํจํ๋ fence์ ์งํฉ์ผ๋ก ๋ง๋ค์ด์ง๋ ๊ฒฝ์ฐ.
1, 2.๊ฐ์ ๊ฒฝ์ฐ๋ ๊ฐ๋จํ๊ฒ ์ฌ๊ท ํจ์๋ฅผ ํธ์ถํด์ฃผ๋ฉด ํด๊ฒฐํ ์ ์์ง๋ง, 3.์ ๊ฒฝ์ฐ ์ฝ๊ฐ์ ๊ณ ๋ฏผ์ค๋ฌ์ ๋ค. ์ฒ์์๋ m์ ํฌํจํ๋ fence์ ์งํฉ์ ์ด๋๊น์ง(์ด๋ ํฌ๊ธฐ๊น์ง) ๊ณ ๋ คํด์ฃผ์ด์ผ ํ๋๊ฐ์ ๋ํด ๊ธฐ์ค์ด ์์ง ์์๊น ์๊ฐ์ ํด๋ณด์๋๋ฐ ๋ช๋ช ๋ฐ๋ก๋ฅผ ์ง์ ์์ผ๋ก ํ๋ฉด์ ๋ง๋ค์ด๋ณด๋ ๊ฒฐ๊ตญ [s, e]๊ตฌ๊ฐ ์ ์ฒด์ ๋ํด์ ๊ณ ๋ คํด์ฃผ์ด์ผ ํจ์ ์ ์ ์์๋ค(์ฆ, ์ -ํ์). 3.์ ํจ์จ์ ์ผ๋ก ๊ณ ๋ คํด์ฃผ๊ธฐ ์ํด์ ๋งค ๋จ๊ณ๋ง๋ค m์ ์ข/์ฐ์ธก ์ธ์ fence ์ค ๋ ๋์ ๋์ด๋ฅผ ๊ฐ๋ fence ์ชฝ์ผ๋ก ํ์ฅํด๊ฐ๋ฉด์ ์ง์ฌ๊ฐํ์ ๋์ด๋ฅผ ๊ณ์ฐํด์ฃผ๋ ๋ฐฉ๋ฒ์ ์ฌ์ฉํ์๋ค. ์ด ๋ฐฉ๋ฒ์ greedy property๋ฅผ ์ฆ๋ช ํ ๋ ์์ฃผ ์ฌ์ฉ๋๋ ๊ธฐ๋ฒ์ ํตํด ์ ๋น์ฑ์ ์ฆ๋ช ํ ์ ์๋ค.
์ด๋ ํ ๋จ๊ณ์์ ์ข/์ฐ์ธก์ fence l, r ์ค ๋ ๋ฎ์ fence l ์ชฝ์ผ๋ก ํ์ฅํ์ฌ ์ง์ฌ๊ฐํ์ ์ต๋ ๋์ด x๋ฅผ ์ป์๋ค๊ณ ํ์. ๋ง์ฝ, ๊ทธ๋ฌํ ๋จ๊ณ์์ r ์ชฝ์ผ๋ก ํ์ฅํ๊ณ ๋ค์ ๋จ๊ณ์์ l๋ก ํ์ฅํ๋๋ผ๋ x์ ๊ฐ์ ๋ณํ์ง ์๋๋ค.
๋ฐ๋ผ์, ๋ฌธ์ ๋ฅผ 1, 2, 3.์ผ๋ก ๋ถํ ์ ๋ณตํ๋ ์ด ์๊ณ ๋ฆฌ์ฆ์ T(n)=2*T(n/2) + n๊ณผ ๊ฐ์ด ๋ณต์ก๋๋ฅผ ๊ธฐ์ ํ ์ ์๊ณ master theorem์ ์ํด T(n)=O(nlgn)์์ ์ ์ ์๋ค. ์ด๋ ์ ํ ์๊ฐ ๋ด์ ๋ฌธ์ ๋ฅผ ํ๊ธฐ์ ์ถฉ๋ถํ ์๊ฐ๋ณต์ก๋์ด๋ค. ๊ตฌํ๊ณผ ๊ด๋ จํด์ ์ฃผ์ํ ๋งํ ์ฌํญ์ผ๋ก๋ ์ฃผ์ด์ง ๊ตฌ๊ฐ [s, e]์ ๋ํ์ฌ 3.์ ๊ณผ์ ์์ (-INF, s) ๋๋ (e, +INF) ๋ฒ์์ fence๋ฅผ ๊ณ ๋ คํ๋ ค๊ณ ํ๋ ๊ฒฝ์ฐ๋ฅผ ์ ์ ํ ์ ์์ธ ์ฒ๋ฆฌํด์ฃผ์ด์ผ ํ๋ ์ ์ด ์๋ค. ๊ตฌ๊ฐ ๋ฐ์ ์์๋ฅผ -INF๋ก ํ์ฌ data guard๋ฅผ ๋๋ ๋ฑ ์ฌ๋ฌ ๋ฐฉ๋ฒ์ด ์์ ์ ์์ง๋ง ๋ ๊ทธ๋ฅ ๋ถ๊ธฐ๋ฅผ ์ฌ์ฉํด์ ์ฒ๋ฆฌํ๋ค.
int solve(int s, int e)
{
// base cases.
if (s > e)
return 0;
if (s == e)
return FENCES[s];
// recursive step(divide in 3 cases).
int m = (s + e) / 2;
int lsub = solve(s, m - 1);
int rsub = solve(m + 1, e);
int l = m;
int r = m;
int h = FENCES[m];
int msub = FENCES[m];
while (s <= l && r <= e)
{
int lh = (l - 1 < s) ? 0 : FENCES[l - 1];
int rh = (r + 1 > e) ? 0 : FENCES[r + 1];
if (lh < rh)
{
++r;
h = min(h, rh);
msub = max(msub, h * (r - l + 1));
}
else
{
--l;
h = min(h, lh);
msub = max(msub, h * (r - l + 1));
}
}
return max(msub, max(lsub, rsub));
}
###๋ฌธ์ ID : FANMEETING(AOJ_FANMEETING.cpp)
2017.01.14.(ํ ).
๋ฌธ์ ๋ฅผ ๋ณด๊ณ ๋ฌด์์ธ๊ฐ ๋นํธ ์ด์ ๊ณฑ์ ์ผ๋ก ๋ฌธ์ ๋ฅผ ํ๋ฉด ๋๊ฒ ๋ค๋ ๊ฐ์ ์ก๋๋ฐ๋ ์ฑ๊ณตํ์ง๋ง ๋ฌธ์ ํ์ด์ ํต์ฌ์ด์๋ Karatsuba๋ฅผ ๋ ์ฌ๋ฆฌ๋ ๋ฐ๋ ์คํจํ๋ค. Karatsuba ์๊ณ ๋ฆฌ์ฆ์ ์์ฉํ๋ฉด O(n^2) ์๊ณ ๋ฆฌ์ฆ์ O(n^lg3) ์๊ณ ๋ฆฌ์ฆ์ผ๋ก ๊ฐ์ ํ ์ ์๋ค. x๋ช ์ ๋ฉค๋ฒ๋ฅผ M(1) ~ M(x)๋ก, y๋ช ์ ํฌ์ F(1) ~ F(y)๋ก ํํํ๊ธฐ๋ก ํ์. ๋ฉค๋ฒ์ ํฌ์ ๋ํ๋ด๋ ๋ฌธ์์ด์ ๊ณฑ์ ์ธ๋ก์์ฒ๋ผ ์ ์ด๋ณด๋ฉด ๋ค์๊ณผ ๊ฐ์ด ๋๋ ๊ฒ์ ์ ์ ์๋ค.
์์ ์ธ๋ก์ ๊ณฑ์ ์ ๋ณด๋ฉด ๊ณฑ์ ๊ฒฐ๊ณผ์ x-1๋ฒ์งธ ์๋ฆฌ๋ถํฐ y-1๋ฒ์งธ ์๋ฆฌ๊ฐ ๊ฐ๊ฐ ํ ๋ฒ์ ๋ผ์ด๋์์ ์ด๋ค์ง๋ ์ ์ ๋๋ ํ๊ทธ์ ์กฐํฉ์ ๋ํ๋ด๊ณ ์๋ ๊ฒ์ ์ ์ ์๋ค. ๋ฐ๋ผ์ 'M'์ 1๋ก, 'F'๋ฅผ 0์ผ๋ก ์๋ฆฌ์ฌ๋ฆผ์ ๋ฌด์ํ์ฌ ์ธ๋ก์์ ๊ณ์ฐํ๋ค๋ฉด [x-1, y-1]๊ตฌ๊ฐ์ 0์ ๊ฐฏ์๊ฐ ๊ณง ์ ์ฒด ํฌ์น์ ๊ฒฝ์ฐ์ ์๋ฅผ ๋ํ๋ด๊ฒ ๋๋ค. ์ด๋, '์๋ฆฌ์ฌ๋ฆผ์ ๋ฌด์ํ์ฌ'๋ผ๋ ๋ถ๋ถ์ด ๊ตฌํํ ๋ ๊น๋ค๋ก์ธ ์๋ ์๋๋ฐ ์ด๋ ๋จ์ํ๊ฒ ๊ณฑํ๋ ์ซ์๋ค์ด ๋ชจ๋ x์ง๋ฒ์ ์๋ผ๊ณ ์๊ฐํ๋ฉด ์ฝ๊ฒ ๊ตฌํํ ์ ์๋ค. ์ธ๋ก์์ ์ดํด๋ณด๋ฉด ๊ฒฐ๊ณผ๊ฐ์ ๊ฐ ์๋ฆฌ์๋ ์ต๋ x๊ฐ ์์ ํฉ์ผ๋ก ๋ง๋ค์ด์ง๊ณ ์ฐ๋ฆฌ๊ฐ ๊ณฑํ๋ ค๋ ์๋ ๋ชจ๋ 0 ๋๋ 1์ด๋ฏ๋ก x์ง๋ฒ์ ๊ฐ์ ํ๋ฉด ์๋ฆฌ์ฌ๋ฆผ์ด ๋ฐ์ํ์ง ์๋๋ค.
์ด์ ๋ ์์ ๊ณฑ์์ [x-1, y-1]๊ตฌ๊ฐ์ 0์ ๊ฐฏ์๊ฐ ์ ์ฒด ํฌ์น์ ๊ฒฝ์ฐ์ ์์ธ ๊ฒ์ ์์์ผ๋ Karatsuba ์๊ณ ๋ฆฌ์ฆ์ ์ฌ์ฉํด์ ๋ ์๋ฅผ ๋น ๋ฆฌ๊ฒ ๊ณฑํ๋ ๋ฐฉ๋ฒ์ ๋ํด์ ์์๋ณด์. ๊ณฑํ๊ธฐ ์ํ๋ ๋ ์ a(y์๋ฆฌ์)์ b(x์๋ฆฌ์)๊ฐ ์ฃผ์ด์ก๋ค๊ณ ํ์(y>=x๋ผ๊ณ ๊ฐ์ ). a, b์ ๋ํด์ ์์ ํ์ m์๋ฆฌ์์ ์์ y-m์๋ฆฌ ์๋ฅผ ๋ถ๋ฆฌํ์ฌ ํํํ๋ฉด axb๋ ์๋์ ๊ฐ์ด ํํ๋ ์ ์๋ค(0<=m<=y).
a x b
= (a1 x BASE^m + a0) x (b1 x BASE^m + b0)
= a1 x b1 x BASE^2m + (a1 x b0 + a0 x b1) x BASE^m + a0 x b0
BASE^m, BASE^2m ์ฐ์ฐ์ ๋จ์ํ shift ์ฐ์ฐ์ด๋ฏ๋ก ๊ณฑ์ ์ผ๋ก ์น์ง ์๋๋ค๋ฉด, ์์ ๊ณฑ์ ์๋ ์ด 4ํ์ ๊ณฑ์ ์ด ํ์ํ๊ฒ ๋๋ค. Karatsuba๋ ์ฌ๊ธฐ์ ํ์ํ ๊ณฑ์ ์ ํ์๋ฅผ 3ํ๋ก ์ค์ด๋๋ฐ (a1 x b0 + a0 x b1) = (a0 + a1) x (b0 + b1) - a1 x b1 - a0 x b0์์ ์ฌ์ฉํ๋ค. ๋งค ๋จ๊ณ m์ ๊ฐ์ ์๋ฆฌ์์ ์ ๋ฐ(์ค์ฐจ1)๋ก ์ค์ ํ๋ค๋ฉด ๊ณ์ฐ์ ๋ณต์ก๋๋ T(n) = 3T(n/2) + cn๊ณผ ๊ฐ์ด ํํ๋๋ค. ์ฌ๊ธฐ์ cnํญ์ ์ ๋ฐ์ ๊ฐ๊น๊ฒ ๋๋ ์๋ค์ ๋ง์ ๋ฐ ๋บ์ ์ ์๋น๋๋ ๊ณ์ฐ๋์ ์๋ฏธํ๋ค. ์ญ์, master ์ ๋ฆฌ๋ฅผ ํ์ฉํด๋ณด๋ฉด ๊ณ์ฐ์ ๋ณต์ก๋๊ฐ O(n^lg3)์ด ๋๋ ๊ฒ์ ํ์ธํ ์ ์๋ค.
vector<int> dq(const vector<int>& a, const vector<int>& b)
{
int asize = a.size();
int bsize = b.size();
// base case.
if (asize == 0 || bsize == 0)
return vector<int>();
if (asize < bsize)
return dq(b, a);
if (asize <= THRESHOLD)
return bf(a, b);
// recursive step.
int m = asize / 2;
vector<int> a0(a.begin(), a.begin() + m);
vector<int> a1(a.begin() + m, a.end());
vector<int> b0(b.begin(), b.begin() + min<int>(b.size(), m));
vector<int> b1(b.begin() + min<int>(b.size(), m), b.end());
vector<int> z0 = dq(a0, b0);
vector<int> z2 = dq(a1, b1);
add(a0, a1, 0);
add(b0, b1, 0);
vector<int> z1 = dq(a0, b0);
sub(z1, z0, 0);
sub(z1, z2, 0);
vector<int> ret;
add(ret, z0, 0);
add(ret, z1, m);
add(ret, z2, m + m);
return ret;
}
###๋ฌธ์ ID : WILDCARD(AOJ_WILDCARD.cpp)
2017.02.05.(์ผ).
ํผ์ง ๊ฝค ๋ฌ๋๋ฐ, ๊ทธ ๋์ README๋ฅผ ์ ๋ฐ์ดํธ๋ฅผ ๋ชปํด์ ํ ๋ฒ์ ์ ๋ฐ์ดํธ ํ๋ค. ์ด ๋ฌธ์ ๋ฅผ ์๊ธฐ ์ฝ๊ณ ๋ช ํํ๊ฒ ํํํด๋ณด๋ฉด ๋ค์๊ณผ ๊ฐ๋ค.
WILDCARD๋ฅผ ํฌํจํ๋ ํจํด์ ๋ํ๋ด๋ pattern[0...n], ์ผ์น ์ฌ๋ถ๋ฅผ ์๊ณ ์ถ์ ๋ฌธ์์ด str[0...m]์ด ์ฃผ์ด์ง ๋, str[0...m]์ด pattern[0...n]์ผ๋ก ํํ๊ฐ๋ฅํ ๋ฌธ์์ด์ธ์ง์ ์ฌ๋ถ๋ฅผ true or false๋ก ๊ตฌํ๋ผ.
๊ฐ๋จํ๊ฒ DP๋ฅผ ์ ์ฉํด์ ๋ฌธ์ ๋ฅผ ํ ์ ์๋๋ฐ, ๋ฌธ์ ๋ฅผ ํ๊ธฐ ์ํด์ ๋ถ๋ถ๋ฌธ์ ๋ฅผ ์๋์ ๊ฐ์ด ์ ์ํ์.
SUB[i][j] := **pattern[i...n]**๊ณผ **str[j...m]**์ด ๋งค์นญ์ด ๊ฐ๋ฅํ์ง์ ์ฌ๋ถ. true or false.
์์ ๊ฐ์ด ์ ์๋ ๋ถ๋ถ๋ฌธ์ SUB[i][j]๋ฅผ ํ๊ธฐ ์ํ base case์ recursive step์ ํํํด ๋ณด๋ฉด ์๋์ ๊ฐ๋ค.
SUB[i][j] =
base case 1) i == n์ธ ๊ฒฝ์ฐ,
๋ ์ด์ ๋์ ์ํฌ pattern์ด ์๋ ์ํ์ด๋ฏ๋ก j == m(์ฆ, str๋ ๋ชจ๋ ์๋น)์ธ ๊ฒฝ์ฐ์๋ง true, ์๋ ๊ฒฝ์ฐ false.
base case 2) j == m์ธ ๊ฒฝ์ฐ,
๋ ์ด์ ์๋นํ str์ด ์๋ ์ํ์ด๋ฏ๋ก pattern[i...n]์ด ๋ชจ๋ '*'๋ง ํฌํจํ๊ณ ์๊ฑฐ๋ i == n(์ฆ, pattern๋ ๋ชจ๋ ์๋น)์ธ ๊ฒฝ์ฐ์๋ง true, ์๋ ๊ฒฝ์ฐ false.
recursive step 1) pattern[i] != '*' && pattern[i] != '?'์ธ ๊ฒฝ์ฐ,
pattern[i] != str[j]์ธ ๊ฒฝ์ฐ false, ์๋ ๊ฒฝ์ฐ SUB[i + 1][j + 1].
recursive step 2) pattern[i] == '*'์ธ ๊ฒฝ์ฐ,
j + 1 <= idx <=m ์ธ idx์ ๋ํ์ฌ SUB[i + 1][idx]๊ฐ ๋ชจ๋ false์ธ ๊ฒฝ์ฐ์๋ง false, ์๋ ๊ฒฝ์ฐ true.
recursive step 3) pattern[i] == '?'์ธ ๊ฒฝ์ฐ
SUB[i + 1][j + 1].
char solve(int wIdx, int nIdx)
{
// base cases.
if (wIdx == WILD.size())
return (nIdx == NAME.size()) ? TRUE : FALSE;
if (nIdx == NAME.size())
{
int idx;
for (idx = wIdx; idx < WILD.size() && WILD[idx] == '*'; ++idx);
return (idx == WILD.size()) ? TRUE : FALSE;
}
// dp step.
char& ret = CACHE[wIdx][nIdx];
if (ret == 0)
{
// dp.
if (WILD[wIdx] == '?')
ret = solve(wIdx + 1, nIdx + 1);
else if (WILD[wIdx] == '*')
{
ret = FALSE;
for (int rep = 0; rep <= NAME.size() - nIdx; ++rep)
{
if (solve(wIdx + 1, nIdx + rep) == TRUE)
{
ret = TRUE;
break;
}
}
}
else
ret = (WILD[wIdx] == NAME[nIdx] && solve(wIdx + 1, nIdx + 1) == TRUE) ? TRUE : FALSE;
}
return ret;
}
###๋ฌธ์ ID : TRIANGLEPATH(AOJ_TRIANGLE.cpp)
2017.02.05.(์ผ).
๊ตณ์ด README๋ฅผ ์ ์ ํ์๊ฐ ๋๊ปด์ง์ง ์์ ์ ๋๋ก ์ฌ์ด DP๋ฌธ์ ์ ์ํ๋ค. ๋ค๋ง, ๋ฌธ์ ๋ฅผ ํ ๋ ๋ถ๋ถ๋ฌธ์ ์ ์ ์๋ฅผ ์ด๋ป๊ฒ ํ๋์ ๋ฐ๋ผ์ ๋ฌธ์ ๋ฅผ ํธ๋ ๊ณผ์ ์ด ๊ฐ๋จํด ์ง ์๋, ๋ณต์กํด ์ง ์๋ ์๋ค๋ ์ฌ์ค์ ์์๋๊ธฐ ์ํด์๋ ๋์์ด ๋๋ ๋ฌธ์ ์ด๋ค. ์ด ๋ฌธ์ ๊ฐ์ ๊ฒฝ์ฐ ๋ถ๋ถ๋ฌธ์ ์ ์ ์๋ฅผ ์๋์ ๋ ๊ฐ์ง ๋ฐฉ๋ฒ์ผ๋ก ํด ๋ณผ ์ ์๋ค.
๋ฐฉ๋ฒ1. SUB[i][j] := arr[i][j]์์ ์์ํ๋ TRIANGLEPATH์ ์ต๋ ํฉ.
๋ฐฉ๋ฒ2. SUB[i][j] := arr[i][j]์์ ์ข ๋ฃํ๋ TRIANGLEPATH์ ์ต๋ ํฉ.
๋ง์ฝ, ์ด ๋ฌธ์ ๋ฅผ ํธ๋๋ฐ ๋ฐฉ๋ฒ2.์ ์ ๊ทผ์ ์ฌ์ฉํ๋ค๋ฉด ๋ชจ๋ ๋ถ๋ถ๋ฌธ์ ๋ฅผ ํ์ด๋ธ ํ ์ผ๊ฐํ์ ๋ฐ๋ณ์ ์์นํ๋ ์์๋ค์ ๋ํด์ ์ต๋ ๊ฐ์ ๊ฐ๋ ์์น๋ฅผ ๋ฃจํ๋ฅผ ๋๋ฉฐ ์ฐพ์์ฃผ์ด์ผ ํ ๊ฒ์ด๋ค. ๋ฐ๋ฉด, ๋ฐฉ๋ฒ1.์ ์ฌ์ฉํ์ฌ ๋ฌธ์ ๋ฅผ ํผ๋ค๋ฉด ๋ชจ๋ ๋ถ๋ถ๋ฌธ์ ๋ฅผ ํ์ด๋ธ ํ ๋จ์ง ์ผ๊ฐํ์ ์ ๊ผญ์ง์ ์ ์์นํ ์์์ ๊ฐ์ด ๊ณง ๋ต์ด ๋ ๊ฒ์ด๋ค(๋ชจ๋ TRIANGLEPATH๋ ๋ฐ๋์ ๊ทธ ์์น์์ ์์ํ๋ฏ๋ก). ๋ฐฉ๋ฒ1.์ ์ฌ์ฉํ์ฌ ๋ฌธ์ ๋ฅผ ํ ๋, base case์ recursive step์ ์๋์ ๊ฐ๋ค(์ผ๊ฐํ์ ๋์ด๋ฅผ h๋ผ๊ณ ํ์).
SUB[i][j] :=
base case) i == h - 1์ธ ๊ฒฝ์ฐ,
๋ ์ด์ ๊ฐ๋ฅํ TRIANGLEPATH๊ฐ ์์ผ๋ฏ๋ก arr[i][j]์ ๊ฐ๊ณผ ๊ฐ๋ค. recursive step) i != h - 1์ธ ๊ฒฝ์ฐ, arr[i][j]๋ถํฐ ์์๋๋ ๋ TRIANGLEPATH์ ๋ํด์ ๋ ํฐ ์ชฝ์ ๋ต์ผ๋ก ํ๋ค. ์ฆ, arr[i][j] + max(SUB[i+1][j], SUB[i+1][j+1]).
for (int h = H - 2; h >= 0; --h)
{
for (int idx = 0; idx < h + 1; ++idx)
TRIANGLE[h][idx] += MAXVAL(TRIANGLE[h + 1][idx], TRIANGLE[h + 1][idx + 1]);
}
###๋ฌธ์ ID : LIS(AOJ_LIS.cpp)
2017.02.05.(์ผ).
์์ฃผ ์ ๋ช ํ DP๋ฌธ์ ๋ก ์ฝ๊ฒ ํ ์ ์๋ค. DPํด๋ฒ ์ด์ธ์๋ O(nlgn)์ง๋ฆฌ ์๋ฃจ์ ์ด ์๋ ค์ ธ ์๋ค. ์ด ํ์ด๋ DPํ์ด ๋ฐฉ๋ฒ์ ๋ณด์ธ๋ค. ๋ถ๋ถ ๋ฌธ์ ์ ์ ์๋ฅผ ์๋์ ๊ฐ์ด ์ค์ ํ๋ค.
SUB[i] := arr[i]์์ ๋๋๋ LIS์ค ์ต๋์ ๊ธธ์ด.
์์ ์ ์์ ํด๋นํ๋ ๋ชจ๋ ๋ถ๋ถ๋ฌธ์ ๋ฅผ ํ์ด์ฃผ๊ณ arr์ ๋ชจ๋ ์์์ ๋ํด SUB์ ์ต๋ ๊ฐ์ ์ฐพ์์ฃผ๋ฉด ๋ต์ด ๋๋ค. SUB[i]๋ฅผ ํ๊ธฐ ์ํ base case์ recursive step์ ์๋์ ๊ฐ๋ค(arr์ ๊ธธ์ด๋ฅผ len์ด๋ผ๊ณ ๊ฐ์ ํ๋ค).
SUB[i] =
base case) i == 0์ธ ๊ฒฝ์ฐ,
LIS๋ฅผ ๋ ์ด์ ๋ง๋ค์ด ๋๊ฐ ์ ์์ผ๋ฏ๋ก ์ต๋ ๊ธธ์ด๋ฅผ ๊ฐ๋ LIS๋ {arr[0]}์ด๋ค. ๋ฐ๋ผ์, SUB[i] = 1. recursive step) i != 0์ธ ๊ฒฝ์ฐ, 0 <= idx < i์ธ idx์ ๋ํด์ SUB[i] = 1 + max(SUB[idx])์ด๋ค. ์ฆ, ๊ฐ์ฅ ๊ธด LIS์ ๋ค์ ์๊ธฐ ์์ ์ ์ถ๊ฐํ๋ค.
// solve.
for (int cur = 0; cur < N; ++cur)
{
CACHE[cur] = 1;
for (int pre = cur - 1; pre >= 0; --pre)
{
if (NUMBERS[pre] < NUMBERS[cur])
CACHE[cur] = MAXVAL(CACHE[cur], CACHE[pre] + 1);
}
}
###๋ฌธ์ ID : JLIS(AOJ_JLIS.cpp)
2017.02.05.(์ผ).
LIS์์ ์กฐ๊ธ์ ๋ณํ์ ๊ฐํ ๋ฌธ์ ์ ๋ถ๊ณผํ๋๋ฐ, base case ์ค์ ์ ์๋ชปํด์ ํธ๋๋ฐ ์ ๋ฅผ ๋จน์๋ค. ์ด ๋ฌธ์ ์ ๋ถ๋ถ๋ฌธ์ ์ ์๋ฅผ ์๋์ ๊ฐ์ด ํ์๋ค(A์ ๊ธธ์ด๋ฅผ n, B์ ๊ธธ์ด๋ฅผ m์ด๋ผ๊ณ ํ์).
SUB[i][j] := A[i], B[j]์์ ์์ํ๋ JLIS์ค ์ต๋์ ๊ธธ์ด๋ฅผ ๊ฐ๋ JLIS์ ๊ธธ์ด.
์ฌ๊ธฐ์, "A[i], B[j]๋ก ์์ํ๋"์ ์๋ฏธ๋ JLIS์ ํฌํจ๋ ์์ ์ค A์ ์ํ๋ ๋ชจ๋ ์์๋ A[i...n-1]์์๋ง ๋ฑ์ฅํ ์ ์๊ณ , B์ ์ํ๋ ๋ชจ๋ ์์๋ B[j...m-1]์์๋ง ๋ฑ์ฅํ ์ ์๋ค๋ ์๋ฏธ์ด๋ค. ์ด๋ฅผ ๋ฐํ์ผ๋ก SUB[i][j]๋ฅผ ํ๊ธฐ ์ํด์ ๊ฒฝ์ฐ์ ์๋ฅผ ๋ ์ฌ๋ ค๋ณด๋ฉด ์๋์ ๊ฐ์ ๊ฒฝ์ฐ๊ฐ ์์ ๊ฒ์ด๋ค.
case1. A[i] ... B[j] ...
case2. B[j] ... A[i] ...
case3. (A[i] == B[j]) ...
์์์ ๋ณด์ธ ๊ฐ๊ฐ์ ๊ฒฝ์ฐ๋ฅผ ์ผ๋์ ๋๊ณ , SUB[i][j]๋ฅผ ํ๊ธฐ ์ํ base case์ recursive step์ ๋ณด์ด๋ฉด ์๋์ ๊ฐ๋ค.
base case1) i == n์ธ ๊ฒฝ์ฐ,
SUB[i][j]๋ B์ ์์๋ง์ ์ฌ์ฉํ์ฌ ๋ง๋ค์ด์ง๋ LIS์ ๊ธธ์ด์ ๊ฐ๋ค.
base case2) j == m์ธ ๊ฒฝ์ฐ,
SUB[i][j]๋ A์ ์์๋ง์ ์ฌ์ฉํ์ฌ ๋ง๋ค์ด์ง๋ LIS์ ๊ธธ์ด์ ๊ฐ๋ค.
recursive step1) **A[i] < B[j]**์ธ ๊ฒฝ์ฐ(case1.์ ํด๋น),
i < ni <= n, A[i] < A[ni]์ธ ni์ ๋ํด์ SUB[i][j] = 1 + max(SUB[ni][j])
recursive step2) **A[i] > B[j]**์ธ ๊ฒฝ์ฐ(case2.์ ํด๋น),
j < nj <= m, B[j] < B[nj]์ธ nj์ ๋ํ์ฌ SUB[i][j] = 1 + max(SUB[i][nj])
recursive step3) **A[i] == B[j]**์ธ ๊ฒฝ์ฐ(case3.์ ํด๋น),
i < ni <= n, A[i] < A[ni], j < nj <= m, B[j] < B[nj]์ธ ni, nj์ ๋ํ์ฌ SUB[i][j] = 1 + max(SUB[i+1][j+1])
์ฌ์ค ๋ฌธ์ ๋ฅผ ์ฒ์ ํ ๋, "SUB[i][j] := A[i], B[j]๋ก ๋๋๋ JLIS์ค ์ต๋์ ๊ธธ์ด๋ฅผ ๊ฐ๋ JLIS์ ๊ธธ์ด"๋ก ์ ์ํ์๋๋ฐ, ์ด ๊ฒฝ์ฐ์๋ ๋ฌธ์ ๋ฅผ ํ ์๋ ์๋ค. ์ด ๋, ๋๊น์ง ๊นจ๋ซ์ง ๋ชปํ๋ ๊ฒ์ base case1, 2 ์๋๋ฐ ์ด๋์์ ๊ฐ ๋ฐ๋์ A ๋๋ B๋ง์ ์ฌ์ฉํ์ฌ LIS๋ฅผ ํ์ด์ด์ผ ํ๋ค๋ ๊ฒ์ ์บ์นํ์ง ๋ชปํด ๋ฌธ์ ๋ฅผ ํ์ง ๋ชป ํ์๋ค. ์์ผ๋ก๋ base case๋ฅผ ์ค์ ํ ๋ ์ฃผ์ํ๋๋ก ํด์ผ๊ฒ ๋ค.
// padding.
A[N] = B[M] = MAXNUM;
for (int i = N - 1; i >= 0; --i)
{
CACHE[i][M] = 1;
for (int ni = i + 1; ni < N; ++ni)
{
if (A[i] < A[ni])
MAX_UPDATE(CACHE[i][M], 1 + CACHE[ni][M]);
}
}
for (int j = M - 1; j >= 0; --j)
{
CACHE[N][j] = 1;
for (int nj = j + 1; nj < M; ++nj)
{
if (B[j] < B[nj])
MAX_UPDATE(CACHE[N][j], 1 + CACHE[N][nj]);
}
}
CACHE[N][M] = 0;
// solve.
for (int i = N - 1; i >= 0; --i)
{
for (int j = M - 1; j >= 0; --j)
{
CACHE[i][j] = (A[i] == B[j]) ? 1 : 2;
if (A[i] < B[j])
{
for (int ni = i + 1; ni <= N; ++ni)
{
if (A[i] < A[ni])
MAX_UPDATE(CACHE[i][j], 1 + CACHE[ni][j]);
}
}
else if (A[i] > B[j])
{
for (int nj = j + 1; nj <= M; ++nj)
{
if (B[j] < B[nj])
MAX_UPDATE(CACHE[i][j], 1 + CACHE[i][nj]);
}
}
else
{
for (int ni = i + 1; ni <= N; ++ni)
{
for (int nj = j + 1; nj <= M; ++nj)
{
if (A[i] < A[ni] && B[j] < B[nj])
MAX_UPDATE(CACHE[i][j], 1 + CACHE[ni][nj]);
}
}
}
}
}
###๋ฌธ์ ID : PI(AOJ_PI.cpp)
2017.02.06.(์).
์ ํ์ ์ธ DP๋ฌธ์ ๋ก ์ฝ๊ฒ ํ ์ ์๋ค. ๊ตณ์ด ๊น๋ค๋ก์ด ์ ์ ์ฐพ์๋ณด์๋ฉด ๋ฌธ์์ด์ ์ฐ์ํ 3~5์๋ฆฌ ํํ์ ๋ฐ๋ผ ๋์ด๋๊ฐ ๊ฒฐ์ ๋๋ ๋ถ๋ถ์ธ๋ฐ ์ด๋ ์๋์ ์ฌ์ค์ ๊นจ๋ซ์ผ๋ฉด ์ฝ๊ฒ ๊ทน๋ณตํ ์ ์๋ค.
๋ฌธ์์ด์ 3~5์๋ฆฌ๋ก ๋์ด ์ฝ๋ ๊ฒฝ์ฐ๋ง ์๊ฐํ๋ค. 8์๋ฆฌ ์ซ์๊ฐ ์์ ๋ 3/3/2์ ๊ฐ์ด ๋์ด ์ฝ๋ ๊ฒ์ ๋ถ๊ฐ๋ฅํ๋ค.
problem description์ ๋ช ์ค ๋ ์ ํ์์ผ๋ฉด ๋ฌธ์ ๋ฅผ ํธ๋ ์ฌ๋๋ค์ด ํผ๋ ์์ด ํ ์ ์์ ๋ฏํ๋ฐ ๋ฌธ์ ์ ์ถ์ฒ๊ฐ CF๋ผ๊ณ ํ๋ ์ฐธ๊ณ ๋์ด๊ฐ๋ ์ ๋ฐ์ ์์ ๋ฏ ํ๋ค.
์ฃผ์ด์ง ์ซ์๋ฅผ PI, PI์ ๊ธธ์ด๋ฅผ n์ด๋ผ๊ณ ํ ๋, ๋ฌธ์ ๋ฅผ ํ๊ธฐ ์ํ ๋ถ๋ถ ๋ฌธ์ ์ ์ ์๋ ์๋์ ๊ฐ๋ค.
SUB[i] := PI[i...n - 1]์ ์ธ์ฐ๊ธฐ ์ํ ์ต์ ๋์ด๋.
์ ์๋ ๋ถ๋ถ ๋ฌธ์ ๋ฅผ ํ๊ธฐ ์ํ base case, recursive step์ ์๋์ ๊ฐ๋ค.
base case1) i == n์ธ ๊ฒฝ์ฐ,
์ธ์ธ ์ซ์๊ฐ ๋ ์ด์ ์๋ ๊ฒฝ์ฐ์ด๋ฏ๋ก SUB[i] = 0.
base case2) i == n - 1 ๋๋ i == n - 2์ธ ๊ฒฝ์ฐ,
์์์ ๋ฐํ๋ฏ ๋ชจ๋ ์ซ์๋ 3~5์๋ฆฌ๋ก ๋์ด์ ์ผ์ด์ผ๋ง ํ๋ค. ๋ฐ๋ผ์, base case2์ ๊ฐ์ด ํ ๊ธ์ ๋๋ ๋ ๊ธ์๋ฅผ ์ธ์ฐ๋ ๊ฒ์ ๋ถ๊ฐ๋ฅํ ๊ฒฝ์ฐ์ด๋ค. ์ด์ ๊ฐ์ ๊ฒฝ์ฐ๊ฐ ๋ต์ ํฌํจ๋์ง ์๋๋ก SUB[i] = +INF๋ก ํ๋ค.
recursive step) 0 <= i < n - 1์ธ ๊ฒฝ์ฐ,
PI[pos...pos + group - 1]๋ก ํํ๋๋ group(3 <= group <= 5)๊ฐ์ ์ซ์๋ฅผ ์ธ์ฐ๊ธฐ ์ํ ๋์ด๋๋ฅผ dif(pos, group)๋ผ๊ณ ํ์. ์ด ๋, SUB[i]๋ ์๋์ ๊ฐ์ด ํํ๋ ์ ์๋ค. ์ด ๋, array bound๋ฅผ ์ฒดํฌํด์ฃผ์ด์ผ ํ๋ ๊ฒ์ ์ฃผ์ ํ๋ค.
SUB[i] = min(CACHE[i + group] + dif(i, group));
// base case.
CACHE[PI.length()] = 0;
CACHE[PI.length() - 1] = 10 * MAXLEN;
CACHE[PI.length() - 2] = 10 * MAXLEN;
// recursive step.
for (int idx = PI.length() - 3; idx >= 0; --idx)
{
for (int group = 3; idx + group - 1 < PI.length() && group <= 5; ++group)
CACHE[idx] = min(CACHE[idx], CACHE[idx + group] + difficulty(idx, group));
}
cout << CACHE[0] << endl;
###๋ฌธ์ ID : QUANTIZE(AOJ_QUANTIZE.cpp)
2017.02.09.(๋ชฉ).
์ค๋ ์๊ฐ์ด ๊ฑธ๋ฆฌ์ง ์๊ณ ํ ์๋ ์์ง๋ง ๋ง์ ํ๊ณ ๋์ ์ค๋ช ํ๋ คํ๋ฉด ๊ฝค๋ ์ ๋ฅผ ๋จน์ด๋ ๋ฌธ์ ์ด๋ค. ๊ฐํน, DP๋ฌธ์ ์ธ ๊ฒ์ ์๊ณ ํ์ด๋ฅผ ์์ํ๋๋ผ๋ ๋ถ๋ถ๋ฌธ์ ๊ด๊ณ์์ ์ฐพ๋ ๊ฒ์ด ์ด๋ ค์ด ๊ฒฝ์ฐ๊ฐ ์๋๋ฐ ์ด๋ฐ ๊ฒฝ์ฐ์๋ ํญ์ ๊ธฐ๋ณธ์ผ๋ก ๋์๊ฐ์ brute-force ์๋ฃจ์ ์ ์๊ฐํด๋ณด๋๋ก ํ์ (์ฃผ์ด์ง ์์ด์ ์ ๋ ฌํ์ฌ ***a[1], a[2], ... ,a[n]***๋ฅผ ์ป์๋ค๊ณ ํ๊ณ , ์ด ์์ด์ S๊ฐ์ ์์ํ ๊ฐ ***q[1], q[2], ... ,q[S]***๋ก ์์ํํ๋ ์ฝ๋๋ฅผ ์๊ฐํด๋ณด๋ฉด ์๋ DPํ์ด๊ฐ ๋น์ฐํ๊ฒ ๋๊ปด์ง)
์ด ๋ฌธ์ ๋ฅผ ํ๊ธฐ ์ํ ๋ถ๋ถ๋ฌธ์ ์ ์ ์๋ ์๋์ ๊ฐ๋ค. ์ฃผ์ด์ง ์์ด์ ์ ๋ ฌํ์ฌ ***a[1], a[2], ... ,a[n]***์ ์ป์๋ค๊ณ ๊ฐ์ ํ์.
SUB[f][q] := a[f...n]์ q๊ฐ์ ์์ ๊ฐ์ ์ฌ์ฉํ์ฌ ์์ํ ํ ๋ ์ค์ฐจ ์ ๊ณฑ์ ์ต์ ํฉ.
์์ ๊ฐ์ด ๋ถ๋ถ ๋ฌธ์ ๋ฅผ ์ ์ํ๋ฉด ์๋์ ๊ฐ์ด base case์ recursive step์ ๋์ถํ ์ ์๋ค.
base case1) f >= n + 1์ธ ๊ฒฝ์ฐ,
๋ ์ด์ ์์ํ ํด์ผํ ๊ฐ์ด ์์ผ๋ฏ๋ก ์ค์ฐจ๋ 0์ด๋ค.
base case2) f < n + 1์ด๊ณ q <= 0์ธ ๊ฒฝ์ฐ,
์์ํ ํด์ผํ ๊ฐ์ ๋จ์ ์์ง๋ง ์์ํ์ ์ฌ์ฉํ ์ ์๋ ๊ฐ์ด ๋จ์์์ง ์์ผ๋ฏ๋ก +INF.
recursive step) f < n + 1 ์ด๊ณ q > 0์ธ ๊ฒฝ์ฐ,
SUB[f][q] := min(sq_error(f, len) + SUB[f + len][q - 1])
์์ recursive step์์ ***sq_error(f, len)***์ด ๋ฑ์ฅํ๋๋ฐ ์ด๋ "a[f...f + len - 1]์ ํ๋์ ๊ฐ์ ์ฌ์ฉํ์ฌ ์์ํ ํ ๋, ์ค์ฐจ ์ ๊ณฑ์ ์ต์ ํฉ"์ผ๋ก ์ ์๋๋ค. ์ด ๊ฐ์ ๊ตฌํ๋ ๊ฒ์ ์ด๋ ต์ง ์์๋ฐ, ํ๋์ ์์ํ์ ์ฌ์ฉ๋๋ ๊ฐ์ ๋ํ์ฌ ์ฃผ์ด์ง ๊ตฌ๊ฐ์ ์ค์ฐจ์ ์ ๊ณฑ ํฉ์ ๊ตฌํ๋ ๊ณต์์ ์ดํด๋ณด๋ฉด ์ด๋ฅผ ํ์ธํ ์ ์๋ค.
f(s, e, q) := a[s...e]๋ฅผ q๋ฅผ ์ฌ์ฉํ์ฌ ์์ํ ํ ๋ ์ค์ฐจ์ ์ ๊ณฑ์ ํฉ
= f(s, e, q)
= (a[s] - q)^2 + (a[s + 1] - q)^2 + ... + (a[e] - q)^2
= a[s]^2 + a[s + 1]^2 + ... + a[e]^2 + (e - s + 1)q^2 - 2q(a[s] + a[s + 1] + ... + a[e])
f(s, e, q)๋ฅผ q์ ๋ํด ๋ฏธ๋ถํ์ฌ f(s, e, q)๊ฐ ์ต์ ๊ฐ์ ๊ฐ๋ ์ง์ ์ ๊ตฌํด๋ณด๋ฉด q = avg(a[s...e])์์ ์ ์ ์๋ค. ์ฆ, ***sq_error(f, len)***์ a[f...f + len - 1]์ a[f...f + len - 1]์ ํ๊ท ๊ฐ์ ์ฌ์ฉํ์ฌ ์์ํ ํ์์ ๋ ์ป์ด์ง๋ ์ค์ฐจ์ ์ ๊ณฑํฉ๊ณผ ๊ฐ๋ค. ์ด๋, ๋ฌธ์ ์์ ์๊ตฌํ๋ S๊ฐ์ ์์ํ์ ์ฌ์ฉ๋๋ ๊ฐ์ ๋ชจ๋ ์ ์์ด๋ฏ๋ก ์์ํ์ ์ฌ์ฉ๋ q๋ฅผ ๋ฐ์ฌ๋ฆผํ์ฌ ์ ์๋ก ์ฌ์ฉํด์ผ ํจ์ ์ฃผ์ํ๋ค.
// init.
for (int row = 0; row < MAX_N + 1; ++row)
{
for (int col = 0; col < MAX_Q + 1; ++col)
CACHE[row][col] = MAX_VAL;
}
for (int row = 0; row < MAX_N + 1; ++row)
CACHE[row][0] = MAX_VAL;
for (int col = 0; col < MAX_Q + 1; ++col)
CACHE[N][col] = 0;
// sort.
sort(ARR, ARR + N);
// solve.
for (int f = N - 1; f >= 0; --f)
{
for (int q = 1; q <= S; ++q)
{
int sum = ARR[f];
int sqr = ARR[f] * ARR[f];
for (int len = 1; f + len - 1 < N; ++len)
{
int avg = (int)((double)sum / len + 0.5);
int var = sqr - 2 * avg * sum + len * avg * avg;
MIN_UPDATE(CACHE[f][q], var + CACHE[f + len][q - 1]);
sum += ARR[f + len];
sqr += ARR[f + len] * ARR[f + len];
}
}
}
###๋ฌธ์ ID : TILING2(AOJ_TILING2.cpp)
2017.02.09.(๋ชฉ).
๋งค์ฐ ์ฌ์ด ๋ฌธ์ ๋ก DP์ ๋ํ์ ์ธ ๋ฌธ์ ์ด๋, ์ฌ์ค ํผ๋ณด๋์น ์์ด์ ๊ตฌํ๋ ๊ฒ๊ณผ ๋ค๋ฆ ์์ด DP๋ฅผ ์ธ ํ์๋ ์๋ค. ์๋ ๊ทธ๋ฆผ๊ณผ ๊ฐ์ด ํ์ผ์ n๋ฒ์งธ ์์น์์ ํ๋์ ์ธ๋ก ํ์ผ๋ก ๋๋๊ฑฐ๋, ๋๊ฐ์ ๊ฐ๋ก ํ์ผ๋ก ๋๋๋ ๊ฒฝ์ฐ ์ธ์๋ ๋ค๋ฅธ ๊ฒฝ์ฐ๊ฐ ์กด์ฌํ์ง ์์ผ๋ฏ๋ก ์์ฃผ ๊ฐ๋จํ๊ฒ ์๋์ ์ ํ์์ ์ป์ ์ ์๋ค.
SUB[i] := 2xi ํ์ผ์ ์ฑ์ฐ๋ ๊ฒฝ์ฐ์ ์
SUB[i] = SUB[i - 1] + SUB[i - 2]
int fibo(int n)
{
if (n == 1)
return 1;
if (n == 2)
return 2;
int p = 2;
int pp = 1;
int cur = p + pp;
for (int i = 3; i < n; ++i)
{
pp = p;
p = cur;
cur = (p + pp) % MOD;
}
return cur;
}
###๋ฌธ์ ID : TRIPATHCNT(AOJ_TRIPATHCNT.cpp)
2017.02.09.(๋ชฉ).
์ด ๋ฆฌํฌ์งํ ๋ฆฌ์ ์๋ TRIANGLEPATH์ ๊ฑฐ์ ์ผ์นํ๋ ๋ฌธ์ ์ด๋ค. ๊ฒฝ๋ก์ ์ต๋๊ฐ์ ๊ตฌํ๋ ๋ฐฉ๋ฒ์ TRIANGLEPATH์ 100% ์ผ์นํ๋ฉฐ, ์ด ๊ณผ์ ์์ ์๋์ ๊ฐ์ด ๋ถ๋ถ๋ฌธ์ ํ๋๋ฅผ ๋ ํ์ด์ค๋ค. h๊ฐ ํธ๋ฆฌ์ ๋์ด๋ฅผ ๋ํ๋ธ๋ค๊ณ ํ์.
SUB2[i][j] := TRIANGLE[i][j]์์ ์์ํ๋ ์ต๋ TRIANGLEPATH์ ๊ฐฏ์.
base case) i == h - 1์ธ ๊ฒฝ์ฐ,
์ต๋์ TRIANGLEPATH๊ฐ ๋จ, ํ๋์ ์์๋ก ๊ตฌ์ฑ๋๊ณ ์ ์ผํ๋ฏ๋ก SUB2[i][j] = 1.
recursive step) 0 <= i < h - 1์ธ ๊ฒฝ์ฐ,
subcase1) **SUB[i + 1][j] > SUB[i + 1][j + 1]**์ธ ๊ฒฝ์ฐ,
๋ฐ๋ก ์๋ ์๋ ์์๋ฅผ ์ด์ฉํด์ผ๋ง ์ต๋์ ๊ฒฝ๋ก๋ฅผ ์ป์ ์ ์์ผ๋ฏ๋ก SUB2[i][j] = SUB2[i + 1][j]
subcase2) **SUB[i + 1][j] < SUB[i + 1][j + 1]**์ธ ๊ฒฝ์ฐ,
์ฐ์ธก ์๋ ์๋ ์์๋ฅผ ์ด์ฉํด์ผ๋ง ์ต๋์ ๊ฒฝ๋ก๋ฅผ ์ป์ ์ ์์ผ๋ฏ๋ก SUB2[i][j] = SUB2[i + 1][j + 1]
subcase3) **SUB[i + 1][j] == SUB[i + 1][j + 1]**์ธ ๊ฒฝ์ฐ,
๋ฐ๋ก ์๋, ์ฐ์ธก ์๋ ์๋ ์์ ์ค ์ด๋ค ๊ฒ์ ์ฌ์ฉํด๋ ํญ์ ์ต๋ ๊ฒฝ๋ก๋ฅผ ์ป์ ์ ์์ผ๋ฏ๋ก SUB2[i][j] = SUB2[i + 1][j] +SUB2[i + 1][j + 1].
// solve.
for (int h = N - 2; h >= 0; --h)
{
for (int pos = 0; pos < h + 1; ++pos)
{
if (PATHSUM[h + 1][pos] > PATHSUM[h + 1][pos + 1])
{
PATHSUM[h][pos] = TRIANGLE[h][pos] + PATHSUM[h + 1][pos];
PATHCNT[h][pos] = PATHCNT[h + 1][pos];
}
else if (PATHSUM[h + 1][pos] < PATHSUM[h + 1][pos + 1])
{
PATHSUM[h][pos] = TRIANGLE[h][pos] + PATHSUM[h + 1][pos + 1];
PATHCNT[h][pos] = PATHCNT[h + 1][pos + 1];
}
else
{
PATHSUM[h][pos] = TRIANGLE[h][pos] + PATHSUM[h + 1][pos];
PATHCNT[h][pos] = PATHCNT[h + 1][pos] + PATHCNT[h + 1][pos + 1];
}
}
}
###๋ฌธ์ ID : SNAIL(AOJ_SNAIL.cpp)
2017.02.27.(์).
์ฝ๊ฒ ํด๊ฒฐํ ์ ์๋ ์ณ์ ์ํ๋ ๋ฌธ์ ๋ก ๋ถ๋ถ๋ฌธ์ ๋ง ์ ์ ์ํด์ฃผ๋ฉด ๊ฐ๋จํ ํด๊ฒฐํ ์ ์๋ค. ๋ฌธ์ ๋ฅผ ํ๊ธฐ ์ํ ๋ถ๋ถ๋ฌธ์ ์ ์ ์๋ ์๋์ ๊ฐ๋ค.
SUB[i][j] := i์ผ์ ๋ฌํฝ์ด๊ฐ j ๋ฏธํฐ ์ด์์ ๋๋ฌํ์ ํ๋ฅ
์์ ๋ถ๋ถ๋ฌธ์ ์ ์์ ๋ง์ถ์ด ๊ธฐ์ ์ฌ๋ก์ ์ฌ๊ท์ฌ๋ก์ ๋ํ ์ ํ์์ ์ธ์ฐ๋ฉด ์๋์ ๊ฐ๋ค.
base case 1) j == 0์ธ ๊ฒฝ์ฐ,
ํญ์ 0 ๋ฏธํฐ์๋ ๋๋ฌ์ด ๊ฐ๋ฅํ๋ฏ๋ก SUB[i][j] = 1.0
base case 2) j == 1์ด๊ณ i != 0์ธ ๊ฒฝ์ฐ,
๋น๊ฐ ์ค๊ฑด ์์ค๊ฑด ์๊ด ์์ด i > 0์ผ ๋ง์ 1๋ฏธํฐ์ ๋๋ฌํ๋ ๊ฒ์ ํญ์ ๊ฐ๋ฅํ๋ฏ๋ก SUB[i][j] = 1.0
base case 3) j != 0 ์ด๊ณ i == 0์ธ ๊ฒฝ์ฐ,
0์ผ ๋ง์ j > 0 ๋ฏธํฐ์ ๋๋ฌํ๋ ๊ฒ์ ๋ถ๊ฐ๋ฅ๋ฏ๋ก SUB[i][j] = 0.0
recursive step)
i์ผ ๋ง์ j๋ฏธํฐ ์ด์์ ๋๋ฌํ๋ ๊ฒฝ์ฐ๋ 'i - 1์ผ์ ์ ํํ j - 1๋ฏธํฐ ์ด์์ ๋๋ฌํ๊ณ ๋น๊ฐ ์ค๊ฑฐ๋ ์ค์ง ์์ ๊ฒฝ์ฐ', 'i - 1์ผ์ ์ ํํ j - 2๋ฏธํฐ์ ๋๋ฌํ๊ณ ๋น๊ฐ ์จ ๊ฒฝ์ฐ'๋ก ๋๋์ด ๋ณผ ์ ์๋ค. ์๋์ ์์ ์ด์ ๊ฐ์ ๊ณผ์ ์ ๋ณด์ธ๋ค. ์ ์์ ๊ฒฝ์ฐ 'j - 1๋ฏธํฐ ์ด์'์ ๊ทธ๋๋ก ์ฌ์ฉํ๊ณ ํ์์ ๊ฒฝ์ฐ '์ ํํ j - 2๋ฏธํฐ'๋ก ๋ฐ๊พธ์ด ๋ฌธ์ ๋ฅผ ํธ๋ ์ด์ ๋ ๊ฐ ๋ถ๋ถ๋ฌธ์ ๊ฐ ๊ฒน์น๋ ๋ถ๋ถ์ ํฌํจํ์ง ์๋๋กํ๋ ์ํจ์์ ์ฃผ์ํ๋ค.
SUB[i][j] = SUB[i - 1][j - 1] + 0.75 * (SUB[i - 1][j - 2] - SUB[i - 1][j - 1])
for (int day = 1; day <= DAY; ++day)
{
for (int h = 2; h <= H; ++h)
{
CACHE[day][h] = 0.25 * CACHE[day - 1][h - 1] + 0.75 * CACHE[day - 1][h - 2];
}
}
###๋ฌธ์ ID : ASYMTILING(AOJ_ASYMTILING.cpp)
2017.02.28.(์).
์ด ๋ฆฌํฌ์งํ ๋ฆฌ์์ ๋ค๋ฃจ๋ TILING2๋ฌธ์ ์ ํฌ๊ฒ ๋ค๋ฅธ ์ ์ ์๋ค. ๋จ์ง, TILING2 ๋ฌธ์ ๋ฅผ ํ์ด์ค ํ์ ๋ถ๋ถ๋ฌธ์ ๋ค์ ๊ฐ์ง๊ณ ๋์นญ ํ์ผ๋ง์ ๊ฒฝ์ฐ์ ์๋ฅผ ๋นผ์ฃผ์ด์ผ ํ๋ค๋ ์ ๋ง์ด ๋ค๋ฅด๋ค. 2 * n(n > 4) ๋๋น์ ์ฌ๊ฐํ์ ์ฑ์ฐ๊ธฐ ์ํ ๋น๋์นญ ํ์ผ๋ง์ ์๋ ์๋์ ๊ฐ์ด ์๋ธ ์ผ์ด์ค๋ฅผ ๋๋์ด ๊ฒฝ์ฐ์ ์๋ฅผ ์ ํ์ฌ ์ค์ผ๋ก์จ ๊ณ์ฐ๋ ์ ์๋ค.
case 1 ) n ์ด ์ง์์ธ ๊ฒฝ์ฐ
case 2 ) n ์ด ํ์์ธ ๊ฒฝ์ฐ
u64t ans = 0;
if (1 == N)
ans = 0;
else if (2 == N)
ans = 0;
else if (3 == N)
ans = 2;
else if (4 == N)
ans = 2;
else if (0 == N % 2)
{
ans += fibo(N);
ans += 2 * MOD;
ans -= 2 * fibo((N - 2) / 2);
ans %= MOD;
ans += MOD;
ans -= fibo((N - 4) / 2);
ans %= MOD;
}
else
{
ans += fibo(N);
ans += MOD;
ans -= fibo((N - 1) / 2);
ans %= MOD;
}
###๋ฌธ์ ID : POLY(AOJ_POLY.cpp)
2017.03.02.(๋ชฉ).
์ ํ์์ ๊ตฌํ๊ธฐ๊ฐ ์กฐ๊ธ์ ๊น๋ค๋กญ๊ฒ ๋๊ปด์ง ์ ์๋ ๋ฌธ์ ์ด์ง๋ง, ๋ถ๋ถ๋ฌธ์ ๋ฅผ ์๋ฆฌํ๊ฒ ์ ์ํ๋ฉด ์ฝ๊ณ ๋น ๋ฅด๊ฒ ํ ์ ์๋ค. n๊ฐ์ ์ ์ฌ์ํ์ผ๋ก ๋ง๋ค ์ ์๋ ๊ฐ๊ฐ์ ํด๋ฆฌ์ค๋ฏธ๋ ธ๋ฅผ ์ต์๋จ์ ์์นํ๋ ์ ์ฌ๊ฐํ์ ๊ฐฏ์๋ก ๋ถ๋ฆฌํ ์ ์๋๋ฐ, n์ด 2์ธ ๊ฒฝ์ฐ, 3์ธ ๊ฒฝ์ฐ์ ๋ํด์ ์๋ฅผ ๋ค์ด๋ณด๋ฉด ์๋์ ๊ทธ๋ฆผ๊ณผ ๊ฐ๋ค.
n = 3์ธ ๊ฒฝ์ฐ๋ฅผ ์ ์ดํด๋ณด๋ฉด, 3๊ฐ ์ ์ฌ๊ฐํ์ผ๋ก ๋ง๋ค ์ ์๋ ์ต์๋จ์ **top(1 <= top <= 2)**๊ฐ ์ ์ฌ๊ฐํ์ด ์กด์ฌํ๋ ํด๋ฆฌ์ค๋ฏธ๋ ธ๋ 3 - top๊ฐ ์ ์ฌ๊ฐํ์ผ๋ก ๋ง๋ค ์ ์๋ ์ต์๋จ์ **under(1 <= under <= 3 - top)**๊ฐ ์ ์ฌ๊ฐํ์ด ์์นํ๋ ํด๋ฆฌ์ค๋ฏธ๋ ธ ์๋จ์ top๊ฐ์ ์ ์ฌ๊ฐํ์ ์ฌ๋ ค๋๋ ๊ฒ์ผ๋ก ๋ง๋ค ์ ์๋ ๊ฒ์ ์ ์ ์๋ค(์ ์์ผ๋ก ํ์ํ ๋ถ๋ถ์ ์ดํด๋ณด๋ฉด). ์ฌ๊ธฐ์ ๋ง์ง๋ง์ผ๋ก ์ต์๋จ์ 3๊ฐ์ ์ ์ฌ๊ฐํ์ด ์์นํ๋ ์ผ์ง์ ๋ชจ์์ ํด๋ฆฌ์ค๋ฏธ๋ ธ๋ฅผ ๋ํด์ค๋ค๋ฉด ์ฐ๋ฆฌ๋ 3๊ฐ ์ ์ฌ๊ฐํ์ผ๋ก ๋ง๋ค ์ ์๋ ๋ชจ๋ ํด๋ฆฌ์ค๋ฏธ๋ ธ๋ฅผ ๊ตฌํ ์ ์๋ค.
์ด ๊ณผ์ ์ ์์์ผ๋ก ๋ํ๋ด๊ธฐ ์ํด์ ๋ถ๋ถ๋ฌธ์ ๋ฅผ ์๋์ ๊ฐ์ด ์ ์ํ์.
SUB[total][top] := total๊ฐ ์ ์ฌ๊ฐํ์ผ๋ก ๋ง๋ค ์ ์๋ ์ต์๋จ์ top๊ฐ ์ ์ฌ๊ฐํ์ด ์์นํ๋ ํด๋ฆฌ์ค๋ฏธ๋ ธ์ ์
์์ ๋ถ๋ถ๋ฌธ์ ์ ๋ฐ๋ผ ๊ธฐ์ ์ฌ๋ก์ ์ฌ๊ท์ฌ๋ก๋ฅผ ์ ์ํด์ฃผ๋ฉด ์๋์ ๊ฐ๋ค.
base case 1) total < top์ธ ๊ฒฝ์ฐ.
์ด ์ ์ฌ๊ฐํ์ ์๋ณด๋ค ๋ง์ ์์ ์ ์ฌ๊ฐํ์ด ์ต์๋จ์ ์์นํ ์๋ ์์ผ๋ฏ๋ก SUB[total][top] = 0.
base case 2) total == top์ธ ๊ฒฝ์ฐ,
total๊ฐ ์ ์ฌ๊ฐํ์ ์ฌ์ฉํ ๋, ์ต์๋จ์ total๊ฐ ์ ์ฌ๊ฐํ์ด ์์นํ๋ ํด๋ฆฌ์ค๋ฏธ๋ ธ๋ ์ผ์ง์ ๋ชจ์์ ํด๋ฆฌ์ค๋ฏธ๋ ธ ๋ฟ์ด๋ค. ๋ฐ๋ผ์, SUB[total][top] = 1.
recursive step) total > top์ธ ๊ฒฝ์ฐ,
top๊ฐ์ ์ ์ฌ๊ฐํ์ total - top๊ฐ์ ์ ์ฌ๊ฐํ์ผ๋ก ๋ง๋ค์ด์ง๋ ์ต์๋จ์ under๊ฐ๊ฐ ์์นํ๋ ํด๋ฆฌ์ค๋ฏธ๋ ธ์ ์์ ์ฌ๋ ค ๋์ผ๋ฉด ๋๋ค. top๊ฐ ์ ์ฌ๊ฐํ์ under๊ฐ ์ ์ฌ๊ฐํ ์์ ์ฌ๋ ค๋์ ์ ์๋ ๋ฐฉ๋ฒ์ ์๋ top + under - 1๊ฐ ์ด๋ฏ๋ก ์๋์ ๊ฐ์ด ์์ ์ป์ ์ ์๋ค.
SUB[total][top] = sum{(top + under - 1) * SUB[total - top][under]}, 1 <= under < top
๋น ๋ฅธ ํ์ด๋ฅผ ์ํด ํ ์คํธ ์ผ์ด์ค์ ์ต๋ ํฌ๊ธฐ์ ๋ํด ๋ชจ๋ ๋ถ๋ถ๋ฌธ์ ๋ฅผ ๋ค ํ์ด ๋์ ๋ค ๊ฐ ํ ์คํธ ์ผ์ด์ค์์ SUB[total][0] + SUB[total][1] + ... + SUB[total][total]์ ๊ตฌํด์ค๋ค๋ฉด ์ข ๋ ํจ์จ์ ์ธ ๊ตฌํ์ด ๊ฐ๋ฅํ๋ค.
// pre-processing.
for (int total = 1; total <= MAXN; ++total)
{
for (int top = 1; top < total; ++top)
{
CACHE[total][top] = 0;
for (int under = 1; under <= total - top; ++under)
{
CACHE[total][top] += (top + under - 1) * CACHE[total - top][under];
CACHE[total][top] %= MOD;
}
}
CACHE[total][total] = 1;
}
// solve.
scanf(" %d", &N);
int ans = 0;
for (int top = 1; top <= N; ++top)
ans = (ans + CACHE[N][top]) % MOD;







