0
点赞
收藏
分享

微信扫一扫

ural1057 Amount of degrees 数位DP


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

15 20

2

2

3

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;
}

 

举报

相关推荐

0 条评论