持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第20天,点击查看活动详情
求给定区间 中满足下列条件的整数个数:这个数恰好等于 个互不相等的 的整数次幂之和。
限制:
思路
数位就是把一个数字按照个、十、百、千等等一位一位地拆开来看看待
比如我们常用十进制,就是进位权是10的数
当然,我们可以有其他进制了,如二进制,八进制,三进制等等
数位DP:
管用伎俩,区间高达
题目,要求一个区间内的满足条件的数,那么,区间具有累加性的话。
我们就可以将区间 转化为 的区间
说回题目
题目明确要求,求B进制下的数位满足k的数字
对于B进制来说,满足整数次幂的系数为1,所以,我们这个题其实只要有0和1就ok,其他都是干扰
那么,我们若是1在此位置的话,我们就可以选0,计算后面的排列组合 若是选1的话,则要继续下去
若是在0这个位置的话,则直接计算完
若是大于1的数的话,则当前这位开始,直接开始计算
代码
#include <bits/stdc++.h>
using namespace std;
const int N = 35;
int x, y;
int k, b;
int f[N][N];
void init(){
for(int i=0; i< N ;i ++)
for(int j =0; j<= i ;j++)
if(!j) f[i][j] =1;
else f[i][j] =f[i-1][j] +f[i-1][j-1];
}
int con(int x, int n) {
return f[n][x];
}
int fun(int x) {
vector<int> ve;
while (x) ve.push_back(x % b), x /= b;
reverse(begin(ve), end(ve));
int n = ve.size();
function<int(int, int)> dfs = [&](int cnt, int idx) -> int {
if (idx == n) return cnt == 0;
if (cnt == 0) return 1;
int t = ve[idx];
if (t > 1) {
return con(cnt, n - idx);
} else if (t == 1) {
return con(cnt, n - idx - 1) + dfs(cnt - 1, idx + 1);
} else if (t == 0) return dfs(cnt, idx + 1);
};
return dfs(k, 0);
}
int main() {
cin >> x >> y
>> k >> b;
init();
cout << fun(y) - fun(x-1)<< endl;
return 0;
}