吐槽這個題各種特判!
簡直比字尾陣列還難寫!(儘管還未寫過字尾陣列……)
所幸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 表示不存在不吉利數字,且最...