link
定義不降數為從左到右各位數字呈非下降關係。
求 \([a,b]\) 之間有多少不降數。
\(1 \leq a \leq b \leq 2^ - 1\) 。
把詢問差分,變為詢問 \([1,n]\) 中不降數的個數。
首先,我們可以 \(dp\) 出 \(x\) 位且最高位為 \(y\) 的不降數的個數:
設 \(f_\) 表示 \(i\) 位,且最高位為 \(j\) 的不降數的個數。
計算的時候可以列舉所有 \(\geq j\) 的數字 \(k\) ,讓 \(f_ \to f_+f_\) ,也就是說:
\[f_ = \sum_^9 f_
\]然後把對於每次詢問,我們可以先把 \(n\) 各位數字分離出來,下文中用第 \(i\) 位表示從右往左數第 \(i+1\) 個數字。
假設當前列舉到了第 \(i\) 位,且 \(n\) 的第 \(i\) 位是 \(x\) ,上一位填的是 \(last\) (如果沒有上一位 \(last=0\) ):
最高位可以填 \(last \sim x-1\) ,此時對後面的填法沒有影響,直接讓答案加上:
\[\sum_^ f_
\]這裡 \(i\) 加一是因為我們的數字是從 \(0\) 開始編號的。
最高位填 \(x\) ,此時需要判斷,如果 \(x < last\) ,那麼不可能填 \(x\) ,直接返回答案即可。否則因為填了 \(x\) 下幾位會有大小限制,所以要讓 \(last\) 變成 \(x\) ,繼續判斷下一位;如果當前已經是最後一位,說明 \(n\) 是乙個不下降數,讓答案加一。
**如下:
#include #include #include #include #include using namespace std;
const int n = 15;
int f[n][n];
inline void init(int n)
inline int solve(int n)
return ans;
}int l ,r;
signed main()
Acwing 1082 數字遊戲
數字 dp 問題往往都是這樣的題型,給定乙個閉區間 l,r 讓你求這個區間中滿足某種條件的數的總數。字首和思想,轉化為 f 0,r f 0,l 1 求解。轉化成求 f n 將上限n轉化成10進製 根據題意轉化為k進製,一般是十進位制 列舉從最高位開始列舉n的10進製的每一位,只要該位的取值小於n的1...
AcWing 1082 數字遊戲
題目傳送門 include using namespace std const int n 20 int a n 數字分離的陣列 int dp n n dp pos pre 表示當前第pos位,pre是指前一位是什麼,這個因素制約了後面的取值個數 功能 統計 0 pos 之間答案 param pos...
AcWing1075 數字轉換 樹形DP 題解
題目傳送門 如果乙個數 x 的約數之和 y 不包括他本身 比他本身小,那麼 x 可以變成 y,y 也可以變成 x。例如,4 可以變為 3,1 可以變為 7。限定所有數字變換在不超過 n 的正整數範圍內進行,求不斷進行數字變換且不出現重複數字的最多變換步數。輸入格式 輸入乙個正整數 n。輸出格式 輸出...