所有的dp關鍵有兩點
1.看出來這是一道dp題 (看時間複雜度)
2.狀態轉移方程!!!!
其中狀態的確立和推出狀態轉移方程是個難點,而且dp題還經常會和其他知識點融合在一起搞你,非常靈活。
先從有跡可循的一些經典dp問題入手
一.數字dp
1.確立狀態
如何確立乙個正確的dp陣列?
dp[pos][state1][state2][….]
首先第一維代表著數字
若是人為規定的話: 0-個位 1-十位 2-百位 3……
那麼後面的state代表的就是所有的的i位數滿足的性質
eg. 如果要記錄所有四的倍數的數量 (當然有更簡單的容斥做法,這裡只是舉個例子)
開 dp[pos][mod]
那麼dp[3][2]代表著所有千位數(0000-9999)中%4餘2的個數
那怎麼確定我們要開那些狀態?
1.題目中明確要求的
2.影響狀態轉移的(前導0什麼的)
例如
和每組資料只有一行,包含三個整數 l_i,r_i,m。
在 [l_i,r_i ] 區間,有多少個數奇偶和等於 m,以及這些數的和(對和取模100000007後輸出)。
描述 給定乙個數 x,設它十進位制展從高位到低位上的數字依次是 a0, a1, …, an - 1,定義交錯和函式:這兩道題非常像,但是不同的地方導致我們的狀態方程也不一樣。f(x) = a0 - a1 + a2 - … + ( - 1)n - 1an - 1
例如:
f(3214567) = 3 - 2 + 1 - 4 + 5 - 6 + 7 = 4
給定 l, r, k,求在 [l, r] 區間中,所有 f(x) = k 的 x 的和,即:
先考慮第一道題:
對於pos位,我們想要得到答案dp[pos][sum] 只需從dp[pos-1][sum-sgn*i]轉移而來,用**來表示的話,就是:
for(int i=0; i<=up; i++)
dp[pos][sum]:pos位數中滿足奇偶和是sum的個數與其總和
我們只需開多開一維sum記錄 pos位數中滿足奇偶和是sum的個數
當前的加減與當前的i有關,與之前和之後的數無關,轉移並不會衝突。
第二道題:
我們能否也和上一題一樣也開 dp[pos][sum]呢?
那好,先來解釋一下 如果只開兩維 dp陣列的意義:
pos位數滿足交錯和為sum時的個數和總和
乍一看沒問題,但當你寫狀態轉移的時候,就會發現狀態該怎麼轉移?
狀態沒法轉移,當前是加,那麼下一位就是減,反之亦然。你沒有辦法區分當前是正是負 還是前導0,當前狀態的不同會導致之後狀態也不一樣。
所以給每個數再加上個性質:當前位的符號
dp[pos][sum][sgn]
sgn: 0-有前導0 ,1-正, -1 負
struct nodedp[30][500][3]; //偏移量240
//第三維代表lead
int a[30];
ll pow[30];
int k;
//lead 0-有前導0 1-正 -1 負
node dfs(int pos,bool limit,int lead,int sum)
; }
if(!limit&& dp[pos][sum+240][lead].num!=-1) return dp[pos][sum+240][lead];
node ans=node;
int up=limit?a[pos]:9;
for(int i=0;i<=up;i++)
return limit?ans:dp[pos][sum+240][lead]=ans;
}ll solve(ll x)
return dfs(pos-1,1,0,k).sum;
}
其他難以確立的狀態還有很多,比如大都會的四維dp,比如各種模數,連續字串。
但最為關鍵的就是記住dp[pos][state1][state2][…]
每多乙個狀態,那麼就是pos位的數進一步被細分,可以看做是各種性質的交集,怎麼去分這個數,就是確立狀態的關鍵。
2.狀態的轉移
其實狀態的轉移多多少少要在確立這個狀態的時候一併考慮到了,畢竟狀態要能正確的轉移,我們才能說這個確立的狀態是對的嘛。
而數字dp的轉移是比較單純的,因為多半就是從高位到地位列舉,從低位到高位轉移,而我們一般都是用數字dp記錄滿足條件數的個數,轉移比較簡單,寫出dp陣列,一般轉移就出來了。
那如果要記錄所有滿足條件數的總和,平方和,別的什麼奇奇怪怪的東西呢?
額,目前就遇到過 和 與 平方和。
和:當前列舉的數×當前的位權×(要轉移到的)低位的滿足某性質的個數+(要轉移到的)低位的滿足某性質的個數
eg:。。。。x 。。。
令x1-xn都是滿足條件的低一位的數
sum = (x+x1)+(x+x2)+
⋯ ⋯
(x+xn) =n×x + x1+
⋯ ⋯
+xn開個struct 記錄num和sum
平方和:
ans
= =
(x+x1)2
' role="presentation" style="position: relative;">(x+
x1)2
(x+x
1)2+
(x+x
2)2 (x+
x2)2
+ ⋯ ⋯
+ (x
+xn)
2 (x+
xn)2
==
n∗x2+2∗
x∗(x
1+x2
+⋯+x
n)' role="presentation" style="position: relative;">n∗x
2+2∗
x∗(x
1+x2
+⋯+x
n)n∗
x2+2
∗x∗(
x1+x
2+⋯+
xn)所以要維護三個值:個數 總和 平方和
eg 二概率dp(期望dp)
感覺都可以用數學簡化,但數學功底不夠,就用dp來湊
dp專題總結
1 做題感覺 大部分時候看到題感覺一頭霧水,在明確告訴這是動態規劃的題時會刻意往這方面想,縮小問題規模。如果沒說的話,可能根本不會朝這方面去想。感覺好難做起來理解起來都很費勁,專題中有很多題是稍微變了一下,就暈了,會在各方面細節出問題。就像登山問題和合唱團問題,感覺他們一模一樣,樣例也通過了,就是過...
總結 筆記 題解 DP專題
c est dur.數字 dp 主要求解的是在給定區間 l,r 中滿足條件的解的個數這一類問題.我們一般把求區間 l,r 轉換成求區間 0,r 和 0,l 1 再將得到的結果相減就是答案.對於 不要62 這個問題,我們可以設 f i j 表示位數為 i 開頭的數為 j 的情況下滿足條件的答案數,但要...
數字DP專題
hdu 2089 不要62 hdu 3555不能出現連續的49 uestc 1307相鄰的數差大於等於2 hdu 3652 出現13,而且能被13整除。hdu 3709平衡數 light oj 1140兩個數之間的所有數中零的個數。lightoj 1032 二進位制數中連續兩個 1 出現次數的和 c...