알고리즘

[BOJ 2806] DNA 발견

dldyou 2024. 3. 25. 22:15

아래와 같이 정의하자.

$C_i$: $i$번째 문자 $(A|B)$

$f(i, A)$: $C_i$까지 봤을 때, 모두 $A$로 만드는 최소 비용

$f(i, B)$: $C_i$까지 봤을 때, 모두 $B$로 만드는 최소 비용

 

$C_i=A$라면,

  • $f(i, A)=\min (f(i-1, A), f(i-1, B) + 1)$
    • $AA\dots AA + A$라면 그대로 유지
    • $BB\dots BB + A$라면 $BB\dots BB$를 모두 $A$로 변경
  • $f(i, B)=\min (f(i-1, A), f(i-1, B)) + 1$
    • $AA\dots AA + A$라면 전체를 $B$로 변경
    • $BB\dots BB + A$라면 $A$를 $B$로 변경

$C_i=B$라면, 

  • $f(i, A)=\min (f(i-1, A), f(i-1, B)) + 1$
    • $AA\dots AA + B$라면 $B$를 $A$로 변경
    • $BB\dots BB + B$라면 전체를 $A$로 변경
  • $f(i, B)=\min (f(i-1, A) + 1, f(i-1, B))$
    • $AA\dots AA + B$라면 $AA\dots AA$를 모두 $B$로 변경
    • $BB\dots BB + B$라면 그대로 유지

이와 같이 진행할 수 있다. 답은 $\min (f(N, A), f(N, B) + 1)$이 된다.

int N, dp[MAXN][2];
char dna[MAXN];

int main(void) {
    fastio;
    cin >> N >> dna;

    if (dna[0] == 'A') {
        dp[0][0] = 0;
        dp[0][1] = 1;
    }
    else {
        dp[0][0] = 1;
        dp[0][1] = 0;
    }

    for (int i = 1; i < N; i++) {
        if (dna[i] == 'A') {
            dp[i][0] = min(dp[i - 1][0], dp[i - 1][1] + 1);
            dp[i][1] = min(dp[i - 1][0], dp[i - 1][1]) + 1;
        }
        else {
            dp[i][0] = min(dp[i - 1][0], dp[i - 1][1]) + 1;
            dp[i][1] = min(dp[i - 1][0] + 1, dp[i - 1][1]);
        }
    }
    cout << min(dp[N - 1][0], dp[N - 1][1] + 1);
    return 0;
}

'알고리즘' 카테고리의 다른 글

[BOJ 4900] 7 더하기  (0) 2024.03.26
[BOJ 17215] 볼링 점수 계산  (0) 2024.03.26
[BOJ 27966] △  (0) 2024.03.25
[BOJ 26008] 해시 해킹  (1) 2024.03.24
[BOJ 11899] 괄호 끼워넣기  (1) 2024.03.22