BOJ 11583 - 인경호의 징검다리

image.png

DP로 풀 수 있다.

2와 5의 개수를 각 수마다 세둔다.

$dp[i]$ 를 $2$ 가 가장 적게 $i$ 에 도달할 때 개수라고 한다면 $O(nk)$ 에 모두 채울 수 있다.

이제 한 번 더 동일하게 $dp[i]$ 를 $5$가 가장 적게 $i$ 에 도달할 수 있는 $5$의 개수라고 하고 돌려준다.

그럼 정답은 $\text{Min}(dp_2[n], dp_5[n])$ 임을 알 수 있다.

void solve() {
   int n, k;
   cin >> n >> k;
   vi two(n), five(n);
   for (int i = 0; i < n; i++) {
      int s;
      cin >> s;
      while (!(s % 2)) two[i]++, s /= 2;
      while (!(s % 5)) five[i]++, s /= 5;
   }

   int ans = 1e9;
   for (int it = 0; it < 2; it++) {
      vi dp(n, 1e9);
      dp[0] = two[0];
      for (int i = 1; i < n; i++) {
         for (int j = max(0, i - k); j <= i - 1; j++) {
            mina(dp[i], dp[j] + two[i]);
         }
      }
      mina(ans, dp[n - 1]);
      swap(two, five);
   }
   cout << ans << endl;
}

Tags:

Categories:

Updated:

Comments