ural1057 Amount of degrees 数位DP

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/sdz20172133/article/details/82390133

 

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

猜你喜欢

转载自blog.csdn.net/sdz20172133/article/details/82390133