hdu 2089 初學數字dp

2022-08-24 01:39:09 字數 2390 閱讀 2646

學習數字dp兩天了,哈哈哈今天我這個菜雞就來分享一下我的學習歷程吧。

就以hdu2089作為模板來講吧。

怎麼講呢,在完全沒有接觸數字dp的時候,第一眼看到的想法就是暴力(畢竟資料不大,其實就算是我會了數字dp看到這題我也會暴力做的,畢竟直接就可以過嗎不是)

暴力寫的是很早以前寫的(不過要打表,不然會超時),我也把暴力寫的**放下面吧。

hdu2089暴力**:

#include#include

int d[1000010

];int c[10

];int e[1000010

];int

main()

if(c[j]==6&&c[j+1]==2

)

}if(!flag)

ans++;

d[i]=ans;

}while(scanf("

%d%d

",&a,&b)!=eof)

return0;

}

當然,暴力碰到一些大數就不行了。所以我們還是乖乖學會數字dp吧。

數字dp一般解決的問題是給你乙個區間[a,b],然後給你一些限定條件,要你求在這樣乙個區間裡,符合限定條件數有多少個。我們一般的思路是先求到0~b的符合條件的個數,然後再求0~a-1的符合條件的個數,然後再相減就是答案了。

下面我們先思考乙個問題:給你乙個區間[29,155],然後要你求數字中不含4的數字個數;

下面我先給出乙個簡單**吧,講起來會簡單點:

樣例簡單**:

#include#includeint digit[15];

int dfs(int len,bool limit)//limit要好好理解一下,指的是限制條件

return ans;//每乙個迴圈結束返回ans的值

}int solve(int x)//求他的各個位上的數字

return dfs(len,true);

}int main()

return 0;

}

廢話說的有點多,其實關鍵就是要注意沒乙個迴圈到****結束,然後搞清楚每乙個搜尋到**結束,搞清楚每個ans的值返回到**,返回的是什麼值。其實個人覺得,ans每次返回的是乙個小迴圈的值,而且,對於乙個更高位的迴圈來說,相對來說,每次返回的是一些平行的值,就像123來說,對於百位來說,十位的0和1就是乙個小迴圈,然後十位0和十位1的ans平行的加入到百位的ans中(不知道能不能聽懂,其實只要懂了就好多了)還有乙個問題,像我們這麼算是不是把00,之類的數也加進去了,其實這個問題也煩了我好一會。但是你有沒有發現,我們算0~b和0~a-1的時候都算了00之類的啊,所以把他們相減,不就減掉了嘛,不影響最終答案啊!!!

為什麼講這是簡單的**呢,發現沒有我們講的是數字dp,上面**中根本就沒有dp!!!那麼問題來了,上面寫錯了嗎,沒有!那麼上面寫的是什麼呢,其實你仔細看就會發現我們每次都是要把每個數都遍歷到個位才能返回1,所以這和直接暴力差不多的。所以現在你該知道,這裡面的dp是幹嘛的了,沒錯,就是來減少時間複雜度的。這裡的dp又叫記憶化搜尋,下面我給出加了dp的樣例**:

#include#include

int digit[15

];int dp[20

];int dfs(int len,bool limit)//

limit要好好理解一下,指的是限制條件

if(!limit)dp[len]=ans;//

這是乙個儲存的操作,即記憶的操作

return ans;//

每乙個迴圈結束返回ans的值}

int solve(int x)//

求他的各個位上的數字

return dfs(len,true);}

intmain()

return0;

}

應該看一下就能懂吧,記憶化搜尋可以減少時間複雜度。上面講的很清楚,這裡不想再多說了,下面直接給出hdu2089的用數字dp做的**,好好理解一下,基本就會了。

hdu2089:

#include#include

#define ll long long

int digst[20

];int dp[20][2

];ll dfs(

int len,bool panduan_6,bool

limit)

if(!limit)

dp[len][panduan_6]=ans;

return

ans;}

ll solve(ll x)

return dfs(len,false,true);}

intmain()

return0;

}

說實話,數字dp到目前為止,我就寫了這一道題。以後還有很多題目要寫,加油吧!少年!

你窺探過我最不安的手,在青春最寒冷的時候。

HDU 2089 數字dp (簡單)

數字dp 和hdu 3555類似,稍微複雜了點點,不同在於,一 多考慮4的情況 二 因為子串是 62 而3555的子串 49 末尾數字不同 所以這題要多加一種情況if num i 2 last 6 last 表示前一位數num i 1 狀態還是一樣 dp i 0 表示所有不含不吉利的數開頭任意 dp...

HDU 2089 數字 dp 入門

可暴力,可dp。參考資料 click me 第二個版本的 參考資料 7k 的板子 第二個版本 在下面 做這道題的時候有兩個疑問 第一 既然在dp中 51 既可以看做 51 也可以看做 0051 或者 000051 那麼51這個數字會不會計算多次。第二 既然狀態轉移保證了數字的合法,在統計的時候是否還...

HDU 2089 數字dp入門

開始學習數字dp.一道昨天看過 思想的題今天打了近兩個小時.最後還是看了別人的 找bug.丟丟 傳說院賽要取消 這麼菜不出去丟人也好吧 include include include include include includeusing namespace std int n,m 數字dp 含6...