Longest Increasing Subsequence
在給定一個序列中
會有很多遞增的子序列
找出當中長度最大的
我們可以維護以第 \(i\) 項為終點的最大LIS大小
並定義為 \(dp[i]\)
接下來就是轉移式的部分!
在原始序列 \(a\) 外,另外維護一個序列 \(b\)
令 \(b_i\) 為使 \(dp[j] = i\) 的最大 \(j\) 的 \(a_j\)
我們可以將陣列掃過一遍
然後對每個元素都放進 \(b\) 裡面
而 \(a_i\) 的位置會是
\(b.lower\_bound(a_i)\)
因此\(b\)最後的大小就會是LIS的大小
這個序列 \(b\) 不會是LIS的長相
可以想想怎麼還原LIS的樣子ㄛ
沒那麼裸,想想怎麼做XD
給一個二維矩陣
求和最大的子矩陣
3 | 2 | -2 | 1 |
-1 | -4 | -1 | 1 |
1 | -1 | 2 | 2 |
0 | -1 | 1 | 1 |
最大二維子矩陣在這
有幾個子矩陣?
Ans:\(O(n^4)\)
好像沒有很好?
定義\(dp[i]\)為以\(i\)為終點的最大連續和
則轉移式為\(dp[i] = max(0,dp[i-1]) + a_i\)
在二維平面上有\(n\)個點,每個點有權重\(w_i\)
你可以以原點\((0,0)\)為圓心
任意選定兩個半徑形成兩個圓
並得到兩個圓間的環所覆蓋的點權重和
求最大權重和
\(n \leq 10^5,|x_i|,|y_i| \leq 10^9, |w_i| \leq 10^4\)
Text
對一個維度枚舉區間
另一個維度正常做最大連續和!
也就是一個維度\(O(n^2)\)
另一個維度\(O(n)\)
乘起來就是\(O(n^3)\)
稍微難一點的變化題
小提示,如何運用資料結構來輔助DP
長得很像但不太一樣的題目
注意這題要想辦法壓到 \(O(n^2)\) ㄛ
給你 \(n\) 個東西,和一個可以乘載量為 \(m\) 的袋子
每個東西有重量 \(w_i\) 和價值 \(v_i\)
問你最大的價值為何
想greedy他?
(用CP值排序)
\(n = 3, m = 6\)
\(w_1 = 4, v_1 = 5\)
\(w_2 = 3, v_2 = 3\)
\(w_3 = 3, v_3 = 3\)
最佳解是取 \(p_2,p_3\)
但用CP值會只取到 \(p_1\)
令 \(dp[i][j]\) 為
考慮前 \(i\) 個物品
容量為 \(j\) 的背包能裝多少東西
此時每個物品有被選與不被選兩種情形
所以我們的轉移式必須涵蓋這兩種狀態
此時你又可以發現,轉移式在轉移到\(dp[i][j]\)時
只會用到\(dp[i-1]\)的資料
因此你可以只要維護當前的\(dp[i]和dp[i-1]\)就好
同時取\(dp[i][j]\)時
你也只需要取 \(dp[i-1][k] s.t. k \leq j\)的資料
因此如果你讓for迴圈從 \(j=k\) 開始遞減
你可以只需要維護\(dp[j]\)就好
你會發現有\(n \times m\)個轉移點
而轉移花費為\(1\)
因此總複雜度為\(O(nm)\)
剛剛上面講得基本上是指01背包問題
但其實還有很多種背包
etc:
有限背包, 無限背包
不過作法其實都是一樣的概念
但在細節上有差異,可以自己想想怎麼做
(還有可分割背包, 大數背包這種跟DP比較沒關係的類似題)
背包是非常常見的經典問題
也有非常多的變化 etc. 很多計數問題
所以熟悉背包的概念非常重要ㄛ
裸題
實作一下剛剛講的東西就好ㄌ
好像哪裡不太一樣了?
懶得打ㄌ(X
現在變成有好幾個group
每個group中只能選一個
除了預算
還多了總量限制ㄛ
給你\(n\)個正整數
問你能不能讓某些數變成負的
使所有數加起來是\(0\)
\(n \leq 100, a_i \leq 1000\)
難難ㄉDP
提示一下,可以用帕斯卡三角形取\(C\)
Longest Common Subsequence
\(|lcs(abcd,bc)| = 2\)
\(|lcs(ace,cae)| = 2\)
\(|lcs(abc,def)| = 0\)
定義 \(dp[i][j]\) 為
字串 \(A\) 的前 \(i\) 項和字串 \(B\) 的前 \(j\) 項的lcs長度
考慮兩種情況,\(A_i = B_j 和 A_i \neq B_j\)
我們可以得到兩種轉移式
裸題
給兩個長度小於1000的字串
求LCS長度
給你兩個字串\(A,B\)
定義一函式 \(f(s,t) = |lcs(s,t)|\times4 - |s| -|t|\)
你可以將 \(A,B\) 分別切為連續子字串 \(A',B'\)
求 \(f(A',B')\) 的最大值
把 \(k\) 次方拆成 2進位
\(O(\lg k)\) 時間計算 \(k\) 次方
這樣就是一個矩陣
\(A\) 是一個 \(2 \times 3\) 的矩陣
如果要表達 \(A\) 的第 \(i\) 行第 \(j\) 列的項,那就是 \(A_{i, j}\)
兩個行數列數都相同的矩陣可以做加法
zerojudge上有題目!
我們若有個 \(n \times m\) 的矩陣 \(A\),和\( m \times p \)的矩陣 \(B\)
則 \(A \times B\) 為 \(n \times p\) 的矩陣
其中,矩陣\( A,B \)可相乘若且唯若 \(A_{col} = B_{row}\)
(以上面為例就是那個 \(m\) 是一樣的)
我們直接示範看看
總之設 \(A,B\) 可相乘,令 \(A \times B = C\)
則 \(C_{ij} = \sum\limits^{A_{col}}_{k=1}A_{ik} \times B_{kj}\)
矩陣乘法複雜度為 \(O(n^3)\)
其實不算太好
但矩陣快速冪題目的矩陣通常不會太大
所以這其實還好
我們這邊先省略掉數學證明
總之矩陣乘法存在結合律
而且也可以對方陣取 \(n\) 次方
所以如果我們將DP式轉為一個矩陣
就可以用很快的時間運算了
題敘大致上是說:有6種西洋棋子可以用
每種棋子都有無限多個
你要取 \(n\) 個棋子排成一列
而國王跟皇后都必須取偶數個
求排列方法數模\(10^8+7\)
\(n \leq 10^9\)
分三種狀態
轉移式呢?
\(dp[n][1] = 4 \times dp[n-1][1] + dp[n-1][2]\)
\(dp[n][2] = 2 \times dp[n-1][1] + 4 \times dp[n-1][2] + 2 \times dp[n-1][3]\)
\(dp[n][3] = dp[n-1][2] + 4 \times dp[n-1][3]\)
令\(dp[n-1][1] = a,dp[n-1][2] = b,dp[n-1][3] = c\),則
我們可以發現,每次往下一項走,都是再乘一次矩陣
所以我們可以把他轉成矩陣的 \(n\) 次方
總而言之
矩陣快速冪可以使用的條件就是
我們的DP轉移式是取固定的狀態
而且都是把那些狀態的值乘上一個常數然後加起來
就能用矩陣快速冪做
恭喜你ACㄌ
給定 \(f_1, f_2, a, b\)
令 \(f_n = bf_{n-1} + af_{n-2}\)
求 \(f_n (n \leq 10^9)\)
有四種顏色(紅藍綠黃)的油漆
而你有 \(n\) 個方塊要上色,且每個方塊只能上一種顏色
其中紅色跟黃色一定要有偶數個
請問有幾種上色方式?
覺得有點熟悉ㄅ
沒錯跟北市賽那題幾乎是一樣ㄉ
給一張圖,\(V \leq 100,E \leq 50000\),可能有重邊
給定一個起點和終點
求恰好經過 \(k\) 條邊的路徑有多少條
(路徑不需要簡單,也就是你一條邊走多少次都沒關係)
\(k \leq 10^{15}\)