Dynamic Programming[2]

建北電資小社課

  • 225班
  • 電子計算機研習社_學術長
  • 綽號807

這我

複習一下

區間 DP

  • 針對一個區間做DP
  • 通常針對區間+1-1
  • 區間間有一定的合併規則
  • 阿不就是分治

區間DP

有兩個人,場上有n個數字x[i],兩人輪流移除頭或尾的一個數字,移除的數字總和就是得分,假設兩人皆聰明,求第一個人的最大得分。

dp[l][r]表示在l、r區間中第一個人比第二個人多拿的分數

對於l==r的情況,如果是第一個人拿那區間dp[l][r]=x[i]

第二個人 dp[l][r]=-x[i]

第一個人

dp[l][r]=max(dp[l+1][r]+x[l],dp[l][r-1]+x[r])

CSES1097 轉移式

第二個人

dp[l][r]=min(dp[l+1][r]-x[l],dp[l][r-1]-x[r])

O(n^2)

位元 DP

  • 把每個是否轉為位元
  • 一堆是否變為數字
  • 用在 \(n\) 個選或不選

位元DP

複雜度 \(O(2^n)\)

dp[i][c]表示最小秒數

c(二進)的0表示未打倒

               1表示已打倒

i代表單前所在位置

 

dp[i][0]=i+1;

打倒

tmp=dp[i][c-j];

不整除t[i]: tmp=下一次地屬出現時間

dp[i][c]=min(dp[i][c],tmp)

O(n \times 2^n)

矩陣快速冪優化

  • 用在轉移次數非常多
  • 且轉移方式固定

矩陣快速冪

  • 表格?
  • 各種運算

矩陣

\begin{bmatrix} 1 & 2 & 3\\ 4 & 5 & 6 \end{bmatrix}

第二列

第一列

第一行

第二行

第三行

  • 完全相同
  • 行數、列數 相等

矩陣=

\begin{bmatrix} 1 & 2 & 3\\ 4 & 5 & 6 \end{bmatrix} = \begin{bmatrix} 1 & 2 & 3\\ 4 & 5 & 6 \end{bmatrix}
  • 同位置對同位置相加
  • 行數、列數 相等

矩陣+

\begin{bmatrix} 1 & 2 & 3\\ 4 & 5 & 6 \end{bmatrix} + \begin{bmatrix} 5 & 7 & 9\\ 1 & 3 & 8 \end{bmatrix} = \begin{bmatrix} 6 & 9 & 12\\ 5 & 8 & 14 \end{bmatrix}
  • 如同加法

矩陣-

\begin{bmatrix} 6 & 9 & 12\\ 5 & 8 & 14 \end{bmatrix} - \begin{bmatrix} 5 & 7 & 9\\ 1 & 3 & 8 \end{bmatrix} = \begin{bmatrix} 1 & 2 & 3\\ 4 & 5 & 6 \end{bmatrix}
  • 一一相乘

矩陣係數積

\begin{bmatrix} 1 & 2 & 3\\ 4 & 5 & 6 \end{bmatrix} \times 5 = \begin{bmatrix} 5 & 10 & 15\\ 20 & 25 & 30 \end{bmatrix}
  • 一一相乘

矩陣乘法

\begin{bmatrix} 1 & 2 & 3\\ 4 & 5 & 6 \end{bmatrix} \times \begin{bmatrix} 7 & 3\\ 9 & 1\\ 5 & 2 \end{bmatrix}
\begin{bmatrix} 1 & 2 & 3\\ 4 & 5 & 6 \end{bmatrix}
\begin{bmatrix} 7 & 3\\ 9 & 1\\ 5 & 2 \end{bmatrix}
\begin{bmatrix} 40 & 11\\ 103 & 29 \end{bmatrix}
  • \(O(log n)\) 求 \(x^n\) 的方法

快速冪 (複習)

矩陣&快速冪

M= \begin{bmatrix} 1 & 2\\ 4 & 3 \end{bmatrix}
A \times M ^ n

A= \begin{bmatrix} 1 \\ 4 \end{bmatrix}

轉移式➡️矩陣

\begin{bmatrix} 1 & 1\\ 1 & 0 \end{bmatrix}

dp[n-1]

dp[n-2]

dp[n-1]

dp[n]

  • 內容一

模板

const int mod = 1e9 + 7;

struct Mat {
    // n*n 方陣 
    ll A[MAXN][MAXN];
    int n;
    Mat(int _n){
        n=_n;
        memset(A, 0, sizeof(A));
    }
};

Mat operator *(const Mat &m1, const Mat &m2) {
    assert(m1.n == m2.n);
    int n = m1.n;
    Mat ret(n);
    for (int i = 0; i < n; ++i) {
        for (int j = 0; j < n; j++) {
            for (int k = 0; k < n; k++) {
                ret.A[i][j] += m1.A[i][k] * m2.A[k][j];
                ret.A[i][j] %= mod;
            }
        }
    }
    return ret;
}

Mat pow (Mat a, int n) {
    Mat ans(a.n);
    for (int i = 0; i < a.n; ++i) {
        ans.A[i][i]=1;
    }
    for (int i=1;i<=n;i<<=1) {
        if (n&i) ans = ans * a;
        a = a * a;
    }
    return ans;
}

小事伸手

\begin{bmatrix} 2 & 0 & 3 & 0 & 0\\ 0 & 1 & 0 & 0 & 4\\ 0 & 1 & 0 & 0 & 0\\ 0 & 0 & 0 & 3 & 0\\ 0 & 0 & 0 & 1 & 0 \end{bmatrix}
r_{n-1}
g_{n-1}
g_{n-2}
b_{n-1}
b_{n-2}
r_{n}
g_{n-1}
g_{n}
b_{n-1}
b_{n}

其他題目

Made with Slides.com