第一次知道數字dp這東西,是在大二新手賽,那時有一道「cutting trees」的題目,現在來看就是水題一道,可以用多種方法水過,可惜當時愣是沒做出來,其他水題也沒做出來,於是被大一虐成翔。抱著學習的態度,我們再來看看這道題。
多組詢問,每組詢問a和b,為[a,b]範圍內,有多少個數是由乙個上公升序列組成,例如「1379」,「1234」等等(0 <= a , b <= 10^9)。
因為題目資料挺小的,雖說直接for迴圈暴力找肯定是超時的,但是深搜就不一樣了,這題用深搜來做的話,可以說直觀又簡單:
#include
using
namespace
std;
int a,b,ans;
void dfs(int tmp) //深搜
int main()
return
0;}
時間複雜度應該還是挺可觀的,至少這個**是可以保證ac的~
然後進入我們今天的正題:數字dp
題目是要求區間【a,b】裡面的由乙個上公升序列組成的數的個數(下面簡稱上公升數)
於是我嘗試用之前學過的動態規劃的思路去思考這個問題,假設乙個狀態dp【i,j】表示最高位是 j 的 i 位數中上公升數的個數,那麼顯然,dp【1,j】= 1 ,我們可以遞推出其他資料:dp【i,j】= ∑ dp【i - 1,k】( i < k <= 9),於是有**:
for(int i=1;i
<=9;i++)
dp[1]
[i]=1;
for(int i=2;i
<=9;i++)
for(int j=1;j
<=9;j++)
for(int k=j+1;k<=9;k++)
dp[i]
[j]+=dp[i-1]
[k];
如果題目是要求統計位數一定的上公升數的個數,那麼我們到這裡就只剩下輸出結果而已,可惜沒那麼簡單,我們的最終結果不僅與位數有關,還跟範圍有關,到這兒只是預處理而已
為了解決題述問題,我們需要把問題轉化成求【0,b】和【0,a-1】上公升數數量相減,那麼我們只要解決【0,b】範圍內的上公升數數量就可以了,我們分兩種情況來考慮:
1)位數小於b:直接套用預處理的資料就可以了
for(int i=1;i//cnt為b的位數
for(int j=1;j<=9;j++)
res+=dp[i][j];
2)位數等於b:好像很難的樣子~~
事實證明,這一部分真的有點難,想了好久依舊得不到乙個比較通用的解法,於是看了看當時ta給的題解,大概是這樣的思路:
首先,你得找到乙個數index,這個index滿足b的前index位為上公升序列。然後從第 1 位到第index位,尋找上公升數,公式如下:
ans = ∑【1~index】∑【b[i-1]+1~b[i]-1】dp【cnt-i+1,j】(有點醜對不住了,不會用公式編輯器)
寫成**:
res=0;
for(int i=1;i<=index;i++)
for(int j=num[i-1]+1;j//num陣列儲存數對應位的數字
res+=dp[cnt-i+1][j];
然後我們再來考慮,為什麼是加法是到index而不是到cnt呢?
因為比原數大的上公升數已經不符合條件。
最後其實算出來的是【1,b-1】中的上公升數,如果需要得到【0,b】,加上頭尾即可,下面是完整**:
#include
using namespace std;
int a,b,ans,dp[15][10];
int cnt,num[10],index;
void fun(int n)
for(int i=1;i<=cnt/2;i++)
swap(num[i],num[cnt-i+1]);
index=1;
while(index+1
<=cnt&&num[index]index+1])
index++;
}int sol(int n)
int main()
return
0;}
以上就是這道題本人的一點看法,歡迎各位大牛指教~ 動態規劃學習系列 數字DP(練手一)
hdu 2089 不要62 題目大意是統計 a,b 區間內沒有4並且沒有62的數,因為有之前那道題的鋪墊,很快想到了解決方法。思路 預處理乙個dp陣列,dp i,j 代表最高位為 j 的 i 位數滿足題述要求的的個數 然後分別統計 0,b 和 0,a 1 區間內滿足條件的數 與之前那題類似,不過更簡...
動態規劃學習系列 數字DP(練手三)
hdu 3652 解題思路 數字dp,狀態dp i j k c 表示 i 位數中,以 j 開頭的,模13為k的數的統計情況,其中 c 可取0或者1,0表示不包含13,1表示包含,這樣我們就可以把所有的數分成兩部分,設計狀態轉移方程。1 狀態轉移方程 dp i j tmp j l 13 1 dp i ...
學習筆記 動態規劃 I 初識DP
更新日期 2018 3 16,2018 12 03 動態規劃,簡稱dp dynamic programming 簡介1簡介2 動態規劃十分奇妙,它可以變身為記憶化搜尋,變身為遞推,甚至有時可以簡化成乙個小小的算式。動態規劃十分靈活,例如 noip2018 pj t3 擺渡車 寫法有很多很多,但時間 ...