CSES 2220 Counting Numbers 題解
本文最後更新於:2022年11月25日 晚上
CSES 2220
題序
給定一個區間 $[a, b](a, b \le 10^{18})$,求區間內有幾個合法的整數,合法的定義為:任兩個相鄰的數字皆不相同,如 $123$ 是一個合法的整數,但 $555$ 不是。
解法
狀態定義
令 $dp_{i ,j}$ 為區間 $[j \times 10^i, (j+1) \times 10^i)$ 內合法的整數個數。
轉移式
可發現,對於所有合法的數字滿足長度為 $i$ 且前端數字為 $j$,那麼這些數字就可以透過在前端加上除了 $j$ 以外的所有正整數來得到一個新的合法整數,因此轉移式便是:$dp_{i, j} = \displaystyle\sum_{k=0, k \neq j}^{9}{dp_{i-1, k}}$
合法個數求法
拿 $2345$ 為例,對於 $\le 2345$ 的所有數字可分為三種:
- $< 2000$
- $2000 \sim 2344$
- $2345$
對於第一種情況答案應該很好算,那就是:$dp_{4, 1} + \sum_{i=0}^{9}{dp_{3, i}} + \sum_{i=0}^{9}{dp_{2, i}} + \sum_{i=0}^{9}{dp_{1, i}}$,而第三種也很簡單,直接判斷就可以了。
至於第二種的部分,我們可以再分成幾種情況:
- $2000 \sim 2299$:前一位數字貼合上限
- $2300 \sim 2339$:前兩位數字貼合上限
- $2340 \sim 2344$:前三位數字貼合上限
假設 $s_i$ 為從前面數來的第 $i$ 位數字(1-based),那麼我們就可以枚舉是前 $i$ 位數字貼合上限,那麼合法的整數數量便是:$\displaystyle\sum_{i=1}^{\log_{10}-1}{\sum_{j=0}^{s_{i+1}}{dp_{i+1, j}}}$
需要額外注意的是像 $555$ 這種數字,如果貼合前兩位的話就已經是不合法的了,這時就需要停止計算
Code
1 |
|