Timus 1057 数位dp

1057. Amount of Degrees

Time limit: 1.0 second
Memory limit: 64 MB
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 = 2 4+2 0,
18 = 2 4+2 1,
20 = 2 4+2 2.

Input

The first line of input contains integers  X and  Y, separated with a space (1 ≤  X ≤  Y ≤ 2 31−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

数位dp入门题,共有K种状态0~k-1分别表示有多少个B的M次幂在其中(i==2以及更大的情况直接排除)。
找到状态后,很容易做了。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<map>
#include<queue>
#include<stack>
#include<vector>
#include<ctype.h>
#include<algorithm>
#include<string>
#define PI acos(-1.0)
#define maxn 40
#define maxm 15
#define INF 1<<25
typedef long long ll;
using namespace std;
int ff[maxn][maxn];
int bit[maxn];
int aa,bb;
int lim,bt;
int solve (int pos,int p,bool cmp)
{
    if(pos==0) return p==lim;
    if(~ff[pos][p]&&!cmp) return ff[pos][p];
    int u=cmp?bit[pos]:bt-1;
    u=min(u,1);
    int ans=0;
    for(int i=0; i<=u; i++)
    {
        int newp;
        if(i==1) newp=p+1;
        else newp=p;
        bool c=(cmp&&(i==bit[pos]));
        if(newp>lim)
        continue;
        ans+=solve(pos-1,newp,c);
    }
    return cmp?ans:ff[pos][p]=ans;
}
int main()
{
    scanf("%d%d%d%d",&aa,&bb,&lim,&bt);
    int pp=0;
    aa--;
    memset(ff,-1,sizeof(ff));
    memset(bit,0,sizeof(bit));
    while(aa)
    {
        bit[++pp]=aa%bt;
        aa/=bt;
    }
    int l1=solve(pp,0,1);
    pp=0;
    memset(ff,-1,sizeof(ff));
    memset(bit,0,sizeof(bit));
    while(bb)
    {
        bit[++pp]=bb%bt;
        bb/=bt;
    }
    int l2=solve(pp,0,1);
    printf("%d\n",l2-l1);
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值