題目大意:spa
密碼串由小寫字母、大寫字母和數字組成,要求求出小寫字母個數很多於L個、大寫字母個數很多於U個、數字個數很多於D個的長度爲N密碼串的種數。密碼
答案對 1000000009 取模時間
解題思路:思考
本身不會,看了neal_wu的代碼,表示膜拜。數字
令a表示小寫字母個數,b表示大寫字母個數,c表示數字個數,則a>=L,b>=U,c>=D,a+b+c=N。枚舉
按照通常來說會首先想到枚舉數字個數再枚舉小寫字母個數,而後就用組合數求種數,這個是最天然的想法,可是時間複雜度不堪忍受。
這題有個規律,
由於數字比較特殊,它只有10種,而小寫字母和大寫字母都是26種,因此小寫字母和大寫字母能夠一塊兒考慮,而後用組合數區分種數,因而先枚舉數字。
當數字個數爲c時,種數num=sum{pow(10,c)*choose(N,c)*pow(26,N-c)*choose(N-c,k)},L<=k<=N-c-U
考慮到c是枚舉量,因此num=pow(10,c)*pow(26,N-c)*choose(N,c)*sum{choose(N-c,k)},L<=k<=N-c-U
因而num的值跟一段連續的組合數求和有關,只要能o(1)求出sum{choose(N-c,k)},L<=k<=N-c-U的值,就能O(1)求出num的值,就能O(n)解決問題。
設H(c)=sum{choose(N-c,k)},L<=k<=N-c-U
能夠得之有遞推式:H(c-1)=2*H(c)+choose(N-c,L-1)+choose(N-c,N-c-U+1);
初始條件: H(N-L-D)=choose(N-c,L);
因此c從N-L-D往下枚舉到D,維護H(c)的遞推值,就能O(n)解決該題。
思考中:
由於這題涉及到楊輝三角中的一個正的三角形,它要求的值ans等於那個三角形的一行的和乘以一個可有可無係數的值的和,因此能夠用一個值維護行的和就能避免O(n^2)枚舉值,下降一維複雜度。
在正三角形中假設H(i)表示第i行的值的和以及第i行是楊輝三角的第Y(i)行,起點是這一行的第X(i)個,
則H(1)=choose(Y(i),X(i))
H(i+1)=2*H(i)+choose(Y(i),X(i)-1)+choose(Y(i),X(i)+i)
在倒三角形中也是能夠遞推H(i)的,H(1)表示最下面的那一個值,
H(1)=choose(Y(i),X(i))
H(i+1)=(H(i)-choose(Y(i)-1,X(i)-1)-choose(Y(i)-1,X(i)+i-1))/2+choose(Y(i)-1,X(i)-1)+choose(Y(i)-1,X(i)+i-1)
也能夠O(1)維護。