区間DPのテーブルを可視化してわかりやすくしてみた

区間DPのテーブルを可視化してわかりやすくしてみた

前回

DP(Dynamic Programming)をVue3.0 With TS & PrimeVUEで視覚化する
やること

区間DP

DP(動的計画法)の中で区間を状態として表すものをいう。

[a,b,c,d]とあった際に、

  • a→b cost 3
  • a→c cost 10
  • b→d cost 2 etc

といったような条件が有り、適切に区切ったさいの 最小、最大のコストを取るか見積もる際などに使われる

※なので今回の区切る個数は 添字0~4の5つとなる

dp[i][j] = (i,j] の最適解 となるように計算していく

イメージ図

参考問題(応用)

https://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=2877

こちらはO(N²M)となる

  • dp[0][0] = 0
  • dp[i][k] = max(dp[i][k], dp[i][k-1] + c[j][i]) ( i > j ≥ 0, M ≥k ≥ 0)

※k = 区切り数

ap-blog-cpp
ap-blog-cpp. GitHub Gist: instantly share code, notes, and snippets.
C++
#include <iomanip>
#include <iostream>
#include <vector>

using namespace std;
template <class T> void chmax(T &a, T b) {
  if (a < b) {
    a = b;
  }
}

int main() {
  int N;
  int M;
  cin >> N >> M;
  vector<long long> points(N);
  for (int i = 0; i < N; ++i) {
    cin >> points[i];
  }

  vector<vector<double>> c(N + 1, vector<double>(N + 1));

  for (int i = 0; i <= N; ++i) {
    for (int j = i + 1; j <= N; ++j) {
      double sum = 0;
      for (int k = i; k < j; ++k) {
        sum += points[k];
      }
      c[i][j] = sum / (j - i);
    }
  }

  const long long INF = 1LL << 60;
  vector<vector<double>> dp(N + 1, vector<double>(M + 1, -INF));
  dp[0][0] = 0;

  for (int i = 0; i <= N; ++i) {
    for (int k = 1; k <= M; ++k) {
      if (k > i) {
        break;
      }
      for (int j = 0; j < i; ++j) {
        chmax(dp[i][k], dp[j][k - 1] + c[j][i]);
      }
    }
  }

  double res = -1;
  for (int i = 0; i <= M; ++i) {
    chmax(res, dp[N][i]);
  }
  cout << fixed << setprecision(10) << res << endl;
}

なかなか、コードからだと動きがイメージしづらいのでNuxtとVuetifyを使ってさくっとテーブルを可視化させていく(今回は例の1つ目の入力値の過程と結果のみ表示)

N = 5
M = 3
points[9,1,2,3,9]

vue-dp/index.vue at main · kooooohe/vue-dp
Contribute to kooooohe/vue-dp development by creating an account on GitHub.

コスト計算済みテーブル

DPテーブル

両方

DPを行う際には、可視化して進めると理解がとても深まり良いですね。ちなみに、最初dpテーブルの初期値を0にしており正しい答えが出ずにハマっておりました。

また、前回同様動きをつけるともっとわかりやすいが、可変の配列に対するVueの仕様でハマったのでそれはまた別の機会に。

とてもおすすめ本

問題解決力を鍛える!アルゴリズムとデータ構造 (KS情報科学専門書) | 大槻兼資, 秋葉拓哉 | 工学 | Kindleストア | Amazon
Amazonで大槻兼資, 秋葉拓哉の問題解決力を鍛える!アルゴリズムとデータ構造 (KS情報科学専門書)。アマゾンならポイント還元本が多数。一度購入いただいた電子書籍は、KindleおよびFire端末、スマートフォンやタブレットなど、様々な端末でもお楽しみいただけます。