HDU 2089 不要62 數字DP 學習筆記

2021-07-31 17:33:55 字數 1169 閱讀 5453

吐槽這個題各種特判!

簡直比字尾陣列還難寫!(儘管還未寫過字尾陣列……)

所幸1a了……要不除錯都懶得除錯

時間複雜度是o(logn),以10為底,這意味著複雜度近乎o(1)……

題目大意:給定[l,r],問其中有多少個數字不包含4和連在一起的62?

很明顯就是數字dp嘛

為了學習數字dp,我們先看乙個簡單題:

給定[l,r],問其中有多少個數字?

學長我有o(1)的做法!(⊙﹏⊙)我們先假定我不會……

發現我們只要用[1,r]的答案減去[1,l-1]的答案即可。

設r=a1a2...ai...alen。

用f[len][0/1]表示當前從左到右處理到第i位了,且前i位是否和r的前i位相等。0表示現在考慮的前i位小於r的i位(這意味著之後無論怎麼填數,數字都是小於r的),1表示相等。

我們採用「刷表」的狀態轉移方法,依次考慮f[i][0]和f[i][1]能轉移到**去。

先看f[i][0],由於前i位已經所以只能轉移到f[i+1][0]。具體來說,第i+1位可以放0,1,...,9這十個數中的任意乙個數,所以f[i+1][0]+=10*f[i][0]。

再看f[i][1],這時如果第i+1位也等於r的第i+1位,那麼可以轉移到f[i+1][1],具體來說f[i+1][1]+=f[i][1](係數為1是因為第i+1為了緊貼上界只能填a(i+1))。

當然也可以填0,1,...,a(i+1)-1這a(i+1)個數字中的某乙個轉移到f[i+1][0]。具體來說f[i+1][0]+=a[i+1]*f[i][1]。

這樣最後f[len][0]+f[len][1]-1就是答案啦(為什麼要減一呢?留給大家思考!)!

邊界:f[1][0]=a1,f[1][1]=1。

這個**如下:

//求1~n中有多少整數 

#include#include#include#define maxlen 10

using namespace std;

int f[maxlen][2],a[maxlen],len;

int main()

return f[len][0][0]+f[len][0][1]+f[len][1][0]+f[len][1][1];

}int main()

return 0;

}

HDU2089 不要62 數字DP

problem description 杭州人稱那些傻乎乎粘嗒嗒的人為62 音 laoer 杭州交通管理局經常會擴充一些的士車牌照,新近出來乙個好訊息,以後上牌照,不再含有不吉利的數字了,這樣一來,就可以消除個別的士司機和乘客的心理障礙,更安全地服務大眾。不吉利的數字為所有含有4或62的號碼。例如 ...

Hdu2089 不要62 數字dp

include includeint dp 10 3 dp i 0 為位數小於等於i且不含62也不含4的數字的個數 dp i 1 為位數為i且首位為2且不含62也不含4的數字的個數 dp i 2 為位數小於等於i且含62或4的數字的個數 int digit 10 void er int wei in...

hdu 2089 不要62 (數字dp)

思路 用變數記錄吉利數,和最高位為2的吉利數還有不是吉利數的個數。code include include includeusing namespace std int dp 10 3 dp i j i表示位數,j表示狀態 dp i 0 表示不存在不吉利數字 dp i 1 表示不存在不吉利數字,且最...