DP 題集 1

關於 DP 的一些題目php


參考資料

DP

  • Rain and Umbrellas
  • Mr. Kitayuta, the Treasure Hunter
  • Power of String 首先咱們最多隻會在一種字母中選擇部分個,不然要麼都選,要麼都不選。以及咱們必定會把其餘字母轉化成一種字母。枚舉要轉化成的字母以及可能選部分的字母,而後就是01揹包DP。複雜度\(O(26^3k)\)
  • Fibonacci String Subsequences 對於這類字符串計數DP,通常就要考慮怎麼去拼接字符串,DP的狀態和字符串的子串有關。\(dp[i][l][r]\) 表示到第 \(i\) 個 Fibonacci 串時,包含了目標串的子串 \([l,r]\) 的子序列的個數。
  • Gerald and Giant Chess 考慮到 \(k=2000\),因此 DP 的狀態必然是和障礙物有關的,\(dp[i]\)表示到達第 \(i\) 個障礙物的路徑上沒有通過其它障礙物的方案數。
  • Buggy Robot \(dp[x][y][i]\) 表示到 \((x,y)\) 這個點,在字符串中走到了第 \(i\) 個位置的最小花費。在 \(BFS\) 中進行狀態轉移,轉移複雜度 \(O(1)\)
  • Group Projects 學到一個DP姿式。分組計數,\(dp[i][j][k]\)表示到第 \(i\) 我的時,有 \(j\) 個組仍是開放的(便可以被選擇)不公平的值的和爲 \(k\) 時的方案數。關鍵就是開放的組這一維,枚舉 \(a[i]\) ,咱們能夠去定義他的行爲,是獨自成組?仍是加入別的組?仍是新建一個開放的組?仍是加入一個組並關閉這個組?顯然不一樣的行爲對應不一樣的狀態轉移。還有因爲咱們知道了開放的組的數量\(j\) ,考慮 \((a[i]-a[i-1])*j\) (\(i\neq0\))(\(a\) 數組先排序) ,就是那些仍然開放的組須要加的不公平的值的和。
  • Increase Sequence \(dp[i][j]\) 表示到第 \(i\) 個數時,有 \(j\) 個還未關閉的區間的方案數(這裏未關閉的意思是尚未肯定區間的右端點)。顯然考慮每個還未關閉的區間,都會給當前點加上 \(1\) ,據此能夠推出狀態轉移方程了。時間複雜度 \(O(n)\)
  • Sereja and Intervals \(dp[i][j][k]\) 表示到第 \(i\) 個數時,還有 \(j\) 個未關閉的區間,已經關閉了 \(k\) 個區間的方案數。對於每一個數,考慮是關閉前面的區間呢(顯然只能關閉第一個未關閉的區間)?仍是新開一個區間?仍是無論這個數。
  • Ducks in a Row 能夠發現翻轉的區間必定不相交,因此能夠考慮 \(DP\)\(dp[o][i][j][k]\) 表示到 \(o\) 這個位置,前面是否翻轉 ( \(i\) ),連續的 \(D\) 的數量爲 \(j\) ,符合條件的\(D\)連續段的數量爲 \(k\) 時所需的最小翻轉次數。由於 \(j*k\leq\)字符串的長度。因此時間複雜度 \(O(n^2)\)
  • Spinning Up Palindromes \(dp[l][r][i][j]\) 表示 \(S[1...l]\) 等於 \(S[r...n]\) 時從 \(dp[l-1][r+1][i'][j']\) 轉移過來,\(l+1\) 是否須要向 \(l\) 進位 (\(i\)) ,\(r\)\(r+1\) 獲得的進位爲 \(j\) 時的最小花費。轉移怎麼好寫怎麼來,大力枚舉使得兩邊相同時要加的數便可。由於 \(l\)\(r\) 具備相關性,因此數組能夠寫成 \(dp[l][i][j]\)
  • Eighty seven 考慮前綴後綴,開兩個 \(bitset\) 類型的 \(DP\) 數組,之前綴爲例,\(dp[i][j][k]\) 表示到第 \(i\) 個數,必定不選 \(j\) 這個位置上的數,選了 \(k\) 個數時全部可能的和(二進制位爲\(1\)表示有這樣的和)。對於後綴的數組,若是二進制位 \(i\) 上的數字爲\(1\),可修改成 \(bit[87-i]=1\),那麼對於詢問,枚舉 \(k\) ,將前綴後綴按位與,檢查是否有二進制位爲\(1\)
  • Candy Chain \(f[l][r]\) 表示刪掉 \(S[l...r]\) 這個子串能獲得的最多的錢。而後 \(dp[i] = max(dp[i-1], dp[j] + f[j+1][i]) (j < i)\)\(dp[len(S)]\) 即爲答案。預處理 \(f[l][r]\),枚舉 \(S\) 的子串 \(s\) 以及全部的待匹配串 \(t\) ,令 \(g[i][j]\) 表示 \(s[1...i]\) 刪除一些字符(或不刪)等於 \(t[1..j]\) 時獲得的最多的錢。\(f[l][r]=g[r][len(t)]\)。也能夠用字典樹優化,將待匹配串建樹,一樣枚舉子串,而後有 \(g[i][j]\) 表示以 \(i\) 結尾的字符串在字典樹上的狀態爲 \(j\) 時能夠獲得的最多的錢,\(f[l][r]=g[r][0]\)。有三種轉移,要麼在字典樹上向下走,要麼刪掉一個區間(能夠藉助已經計算出的 \(f[l][r]\) 轉移),要麼刪掉 \(j\) 這個狀態表明的字符串。
  • Mahmoud and Ehab and yet another xor task 考慮異或集合的性質(對於任意兩個數,他們的異或值都在集合中),對於一個數 \(a[i]\) 若是 \(a[i]\) 不在集合中,那麼對於集合中的任意數 \(x\)\(a[i]\ xor\ x\) 都不會在集和中。維護一個集合,枚舉 \(a[i]\) ,若是發現 \(a[i]\) 已經在集合中,全部數的構成方案數都翻倍,不然把這個數和集合中全部的數分別異或並加入集合。能夠發現這樣須要離線處理,另外一種作法,經過預處理線性基在線回答詢問。
  • Compute Power 求最小比率,二分答案 \(x\) ,若存在更優的答案,則有 \(\sum\frac{a_i}{b_i}<x\),判斷是否存在 \(\sum{a_i}-x*{b_i}<0\)。先把給的東西按 \(a\) 從大到小排序,考慮 \(dp[i][j][k]\) 表示到第 \(i\) 個時,等於 \(a[i]\) 的數量爲 \(j\) ,大於的數量爲 \(k\),根據是否選擇進行轉移。

樹形DP

  • Appleman and Tree
  • Counting on Tree
  • Tree Pruning 雖然 \(O(nk^2)\) 能夠過,可是有\(O(nk)\)的作法,考慮先預處理出 DFS 序再 DP。
  • Road Improvement 0 沒有逆元,因此不能直接除。對於一個結點,他的兄弟結點的方案數的乘積能夠經過預處理前綴後綴獲得。

狀態壓縮DP

  • Little Pony and Harmony Chest 狀態中0/1表示是否存在某個素數,最多隻有17個素因子。
  • Remembering Strings 一維數組,時間複雜度\(O(m2^n)\)。狀態中0/1表示某個單詞是否變成好記的單詞了。
  • Another Sith Tournament \(dp[i][S]\) 表示擂主爲 \(i\) 時,活着的人狀態爲 \(S\) 時主角能獲勝的機率,\(dp[0][1]=1\)。時間複雜度\(O(n^22^n)\)
  • Exciting Finish! 注意到題目求的是有多少種不一樣的排名,即分數不一樣排名相同屬於同一種狀況。又分配的分數呈不降低,因此當咱們分配一個分數給某人時,能夠當成也給其餘未分配的人分配了相同的分數,那麼要使一我的的分數變成最大,只須要比較初始分數便可。\(dp[s][i][j]\) 表示人的狀態爲 \(s\) ,上一次分配的人是 \(i\),還剩下分數 \(j\) 未分配的方案數。記憶化搜索實現。
相關文章
相關標籤/搜索