Create a code to determine the amount of integers, lying in the set [X;Y] and being a sum of exactly K different integer degrees of B.
Example. Let X=15, Y=20, K=2, B=2. By this example 3 numbers are the sum of exactly two integer degrees of number 2:
17 = 24+20,
18 = 24+21,
20 = 24+22.
Input
The first line of input contains integers X and Y, separated with a space (1 ≤ X ≤ Y ≤ 231−1). The next two lines contain integers K and B(1 ≤ K ≤ 20;2 ≤ B ≤ 10).
Output
Output should contain a single integer — the amount of integers, lying between X and Y, being a sum of exactly K different integer degrees of B.
Sample
input |
output |
|
|
Problem Source: Rybinsk State Avia Academy
算法分析:
数位DP
题意:
求的数为互不相等的幂之和,亦即其B进制表示的各位数字都只能是0和1。求的数为互不相等的幂之和,亦即其B进制表示的各位数字都只能是0和1。题意转化为:给出一个区间,问这个区间内的数,转换成B进制后,刚好有B个1的的数有多少个。
分析: 数位Dp思想,从高位枚举统计思想,套模板就行,不过有几点要注意代码一注释。
代码实现:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
using namespace std;
typedef long long ll;
int a[20];
int dp[40][20];
int k;
ll dfs(int pos,int sta,bool limit)
{
if(pos==-1) return sta==k; //注意不止要循环多少位,还要满足位数
if(sta>k) return 0;
if(!limit && dp[pos][sta]!=-1) return dp[pos][sta];
int up=limit ?min(a[pos],1) : 1;
ll tmp=0;
for(int i=0;i<=up;i++)
{
if(i==0) tmp+=dfs(pos-1,sta,limit && i==a[pos]) ;
else
tmp+=dfs(pos-1,sta+1,limit && i==a[pos]) ;
}
if(!limit) dp[pos][sta]=tmp;
return tmp;
}
ll solve(int x,int b)
{
int pos=0;
while(x)
{
a[pos++]=x%b;
x/=b;
}
return dfs(pos-1,0,true);
}
int main()
{
int x,y,b;
while(~scanf("%d%d%d%d",&x,&y,&k,&b))
{
memset(dp,-1,sizeof dp);
printf("%lld\n",solve(y,b)-solve(x-1,b));
}
return 0;
}