題解 AcWing 1082 數字遊戲

2022-06-12 01:36:08 字數 1058 閱讀 4502

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。輸出格式 輸出...