(待完成)qbxt2019.05 总结2 - 数位DP
數(shù)位 DP 嚴格來說其實并不是 DP……它只是個單純的計數(shù)問題
但是怎么說呢……現(xiàn)在大家似乎都把數(shù)位 DP 叫這個名字,所以……我們還是……叫它 DP
額什么是數(shù)位 DP 呢?
一句話概括——一類求在 K 進制下m滿足條件的數(shù)的數(shù)量有多少個的算法
常見的問題形式:
求 [l..r] 之間的在 K 進制下滿足條件 F 的數(shù)有多少個?
什么?你說for (int i = l ; i <= r; i++) ans+=check(i);?
別學競賽了,回家養(yǎng)鯤吧
我們很快就會發(fā)現(xiàn),數(shù)位 DP 的復雜度和位數(shù)相關,所以一般數(shù)據(jù)規(guī)模奇大
(以上摘自lyd課件)
數(shù)位DP
(以下基于k進制討論)
數(shù)位DP一般會讓你求\([l,r]\)滿足條件的個數(shù),這里我們設函數(shù)\(c(x)\)表示小于x的正整數(shù)中滿足條件的個數(shù),則最終答案就是 \(c(r+1)-c(l)\) 。但k進制時加一操作不一定好實現(xiàn),所以更常用的是 \(c(r)-c(l)+\text{對r的特判結果}\)。
所以問題轉化為求\(c(x)\)。
正如它名字中的“數(shù)位”,DP狀態(tài)的第一維通常是數(shù)字的位數(shù)。所以只要寫出轉移方程,就可以得到小于\(k^x\)的滿足條件的個數(shù)(其中x是任意/給定正整數(shù))即\(\sum dp[x][...]\)
現(xiàn)在要求\(c(x)\)。設\(x\)有\(l\)位,且現(xiàn)在已經(jīng)求得了\(dp[l-1][...]\)。現(xiàn)在考慮最高位,分為兩種不同的情況:
滿足條件的y的最高位小于x的最高位。這時能保證\(y<x\),所以后面任意選。
滿足條件的y的最高位等于x的最高位。這時可以遞歸解決后面的位構成的子問題。但我們發(fā)現(xiàn)遞歸完全是浪費,因為子問題求出的dp數(shù)組是一樣的。所以在子問題中真正有用的是求情況1和遞歸下一層。
因為遞歸的層數(shù)是遞減的,于是我們可以把遞歸改為循環(huán)。
上面這些抽象的描述說實話我都看不懂QAQ
考慮這樣的一道題目:求\([l,r]\)中不包含4和62的數(shù)的個數(shù)。
那么就可以設\(c(x)\)為小于\(x\)的數(shù)中不包含4和62的數(shù)的個數(shù),最終答案即為\(c(r+1)-c(l)\)。
這里可以設\(dp[i][j]\)表示長度為i位的,最高位是j的滿足條件的數(shù)的個數(shù)。然后我們可以寫出這樣的轉移方程:\(dp[i][j](j\neq4)=sum\{dp[i-1][k]|\text{當}j=6\text{時}k\neq2\}\)
下面假設x有l(wèi)位,最高位是x[1],最低位是x[l],其他類似。這一段代碼求出了dp數(shù)組。
for(int j=0;j<=9;j++){if(j==4)continue;dp[1][j]=1; } for(int i=2;i<=l;i++){for(int j=0;j<=9;j++){if(j==4)continue;for(int k=0;k<=9;k++){if(j==6&&k==2)continue;dp[i][j]+=dp[i-1][k];}} }然后考慮情況一。
int ans=0; for(int j=0;j<x[1];j++){if(j==4)continue;ans+=dp[l][j]; }然后是情況二。先寫遞歸版。(toint表示將數(shù)組表示的數(shù)字轉換成int,toarr則相反)
ans+=c(從前面去掉1位的x);這時我們可以發(fā)現(xiàn),在第一次遞歸里有用的代碼是如下的部分:
for(int j=0;j<x[2];j++){if(j==4||(j==2&&x[1]==6)continue;ans+=dp[2][j]; } ans+=c(從前面去掉2位的x);所以最終我們應該把代碼修改為這樣子:
int ans=0; for(int i=l;i>=1;i--){for(int j=0;j<x[l-i+1];j++){if(j==4||(j==2&&x[l-i]==6))continue;ans+=dp[i][j];} }轉載于:https://www.cnblogs.com/water-lift/p/10809884.html
總結
以上是生活随笔為你收集整理的(待完成)qbxt2019.05 总结2 - 数位DP的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: VS2017生成一个简单的DLL文件 和
- 下一篇: 2018-2019-2 20175223