設 \(s\) 是長度為 \(w\) 的 \(01\) 串。從串的右邊開始,每 \(k\) 個字元分成一段(最後不夠 \(k\) 個字元的也分成一段),組成乙個小於 \(2^k\) 的數。然後這 \(\left\lceil\frac\right\rceil\) 個數將組成乙個序列。若這個序列除去前導零後的長度不小於 \(2\) 且序列裡的數嚴格遞增,那麼 \(s\) 就是乙個合法的串。求所有合法的串的個數。
計數題。一開始就往組合方面想了。這個直覺似乎是對的。
先除去第乙個數不看,即強制選 \(0\)(因為它可能不是 \(2^k\),比較特殊),那麼對於後面的 \(\lfloor \frac \rfloor\) 個數,如果直接取的話,每個數都可以取 \(0\) ~ \(2^p-1\),要滿足嚴格遞增,實際上就是在這 \(2^p\) 個數裡面選 \(\lfloor \frac \rfloor\) 個來組成序列,那麼方案就是
\[\binom \rfloor}
\]這樣對嗎?你會發現這是錯的。因為可以有前導零,而且前導零並不是單增的。這就提示我們將前導零拋開,分步計算。現列舉乙個 \(i\) ,強制後 \(i\) 個數不為 \(0\),有 \(2^k-1\) 種,前面剩下的數全部是 \(0\),有 \(1\) 種,那麼總方案數實際上是
\[\sum_^ \rfloor} \binom
\](序列長度大於等於 \(2\) ,\(i\) 要從 \(2\) 開始列舉)
現在將第乙個數不為 \(0\) 的方案加進來,列舉 \(i\) 表示第乙個數選什麼,那麼對於後面 \(\lfloor \frac \rfloor\) 個數,就在大於 \(i\) 的數裡面選。方案就有
\[\sum_^} \binom \rfloor}
\]答案就是
\[\sum_^ \rfloor} \binom + \sum_^} \binom \rfloor}
\]考慮怎麼求這個東西,我們發現 \(k\) 是乙個很小的數,而對於 \(n,\(\binom=0\),所以只需要預處理出 \(n<2^9\) 以內的組合數,用公式直接遞推即可。
(加了一些邊界判定,感性理解即可)
#include#include#define n (1<<9)
int n,k;
inline int max(int x,int y)
struct big
big operator +(const big x)
if(cur) c.num[++c.len]=cur;
return c;
}inline void print()
}c[n][n];
inline int min(int x,int y)
ans.print();
}}// 3 7
2 k進製數
遞推 高精度 f i j 表示共i位且最高位是j的方案數,顯然有只要上一位比它大就可以轉移,所以有f i j f i 1 j 1 f i 1 2 k i 1 也就是f i j f i j 1 f i 1 j 最後特判一下最後一段剩下的w k的就可以。注意高精 include using namesp...
2 k進製數
發現自己推得組合數好像不太一樣 先把這個複雜的柿子寫一遍 sum right rfloor c sum text textk 1 c right rfloor 感覺這個柿子非常蛇皮 但是非常好求啊 由於 2 k 1 非常小,最大僅僅是 511 所以我們沒有什麼必要預處理階乘,我們可以直接用組合數遞推...
2 k進製數(藍橋杯)
思路 首先就是理解題意,這道題我看了一天了,現在還是沒整出來,錯誤50 可能是中間產生溢位了。這是一道組合題,重點就是最高位的選取,我們分成兩種情況來考慮 if m錯誤50 待更 更新 就是沒有注意寫的組合數函式還必須滿足的乙個條件 m n include include includeusing ...