題目大意:
求給定區間 [x,y] 中滿足下列條件的整數個數:這個數恰好等於 k 個互不相等的 b 的整數次冪之和。
例如,設 x=15,y=20,k=2,b=2,則有且僅有下列三個數滿足題意:
17=24+20
18=24+21
20=24+22
輸入格式
第一行包含兩個整數 x 和 y,接下來兩行包含整數 k 和 b。
輸出格式
只包含乙個整數,表示滿足條件的數的個數。
資料範圍
1≤x≤y≤231−1,
1≤k≤20,
2≤b≤10
解題思路:
把num轉換成b次冪的數,然後讓b次冪的每一位為1的總和為k個即可,這就轉換到了數字dp問題,然後再分情況討論:
對於數字num,存放其每一位上的數字(b進製表示下),從高位向低位列舉,假設列舉到第i位,第i位上的數字是x,那麼分以下幾種情況討論:
1.x == 0
1. 那麼第i位只能是0,後面數字上現在都不能確定,只能繼續向後看.
2.x == 1
這裡第i位可以分成兩種情況:
1.第i位放0,那麼後面的數字上可以放k-last個1,res += f[i][k-last];
2.第i位放1,那麼後面數字上的情況不能用組合數計算,因為要保證答案中的數字比原數字要小
3.x > 1
同樣第i位分成兩種情況:
1.第i位放0,那麼後面的數字上可以放k-last個1,res += f[i][k-last];
2.第i位放1,那麼後面的數字上可以放k-last-1個1,res += f[i][k-last-1];
code:
#include
#include
#include
#include
#include
#include
#include
#define inf 0x3f3f3f3f
using
namespace std;
typedef
long
long ll;
typedef pair<
int,
int> pii;
const
int maxn=50;
int k,b;
int f[maxn]
[maxn]
;void
init()
}}intdp
(int n)
else}if
(!i&&last==k) res++;}
return res;
}int
main()
AcWing 1081 度的數量
度的數量 求給定區間 x,y 中滿足下列條件的整數個數 這個數恰好等於 k 個互不相等的 b 的整數次冪之和。例如,設 x 15,y 20,k 2,b 2 則有且僅有下列三個數滿足題意 17 2 4 2 0 18 2 4 2 1 20 2 4 2 2 輸入格式 第一行包含兩個整數 x 和 y 接下來...
AcWing1081 度的數量(數字dp)
對於數字dp的題目,我學習的是y總的模板,也就是說把所有數先用拆位後考慮從頭開始考慮,形成乙個樹的形狀 左分支為填0 ai 1的情況,這列情況一般可以通過數學公式一次性求出,之後右分支就填當前數,這樣向下延申,在最後特判右分支的情況,也就是乙個數 對於數字dp,一般儲存兩個量,乙個是個數,乙個是la...
AcWing 連通塊中點的數量
給定乙個包含n個點 編號為1 n 的無向圖,初始時圖中沒有邊。現在要進行m個操作,操作共有三種 c a b 在點a和點b之間連一條邊,a和b可能相等 q1 a b 詢問點a和點b是否在同乙個連通塊中,a和b可能相等 q2 a 詢問點a所在連通塊中點的數量 第一行輸入整數n和m。接下來m行,每行包含乙...