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\),接下来两行包含整数 \(K\)\(B\)

输出格式
只包含一个整数,表示满足条件的数的个数。

数据范围
\(1 \le X \le Y \le 2^{31} - 1\),

\(1 \le K \le 20\),

\(2 \le B \le 10\)

输入样例

15 20
2
2

输出样例

3

算法1

数位DP,时间复杂度:\(O(N^2)\)

C++ 代码

#include <iostream>
#include <algorithm>
#include <vector>

using namespace std;

const int N = 35;

int k, b;
int f[N][N]; //f[i][j]: 表示有i位数,其中1的个数为j的所有集合。属性:方案数

void init() {
    for (int i = 0; i < N; ++i) {
        for (int j = 0; j <= i; ++j) {
            //C(i, j) = C(i  -1, j) + C(i - 1, j - 1)
            if (!j) f[i][j] = 1;
            else f[i][j] = f[i - 1][j] + f[i - 1][j - 1];
        }
    }
}

int dp(int n) {
    if (!n) return 0;
    
    vector<int> bits;
    while(n) bits.push_back(n % b), n /= b;
    
    int ans = 0;
    int last = 0; //已经选了1的个数
    for (int i = bits.size() - 1; i >= 0; --i) {
        int x = bits[i];
        
        // if (!i && last == k) ans ++; 
        // if (x == 0) continue;
        // if (x == 1) {
        //     ans += f[i][k - last];
        //     last ++;
        //     if (last > k) break;
        // } else if (x > 1) {
        //     ans += f[i + 1][k - last]; // 当x大于1时,有i + 1 位数
        //     break;
        // }
        
        if (x) { //只有x大于0时,才能取(0, x - 1)时,后面的位可以任意选,这里保证了x > 0,所以保证了当x为0时一定可以任意选
            ans += f[i][k - last];
            if (x > 1) { //同理只有x > 1,当x为1时,后面的其余位才能任选
                if (k - last - 1 >= 0) ans += f[i][k - last - 1];
                break; //x不能取大于1的数,直接break
            } else { //x == 1
                last++;
                if (last > k) break;
            }
        }
        
        if (!i && last == k) ans ++; //该数本身是否满足要求
    }
    return ans;
} 

int main() {
    int l, r;
    cin >> l >> r >> k >> b;
    
    init();
    
    cout << dp(r) - dp(l - 1) << endl;
    return 0;
}
posted @ 2020-10-30 15:20  咕咕咕OI  阅读(169)  评论(0)    收藏  举报