Timus Online Judge 1057. Amount of Degrees(数位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 exactlyK 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

/*
题意: 求一个区间的 degree进制的1的个数为k的数的个数
思路:数位dp,一定要注意是1个个数为k  dp[i][j][k] 代表到达了i位的j进制还差k个1

具体注意的地方写在了代码中
*/

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<queue>
#include<stack>
#include<vector>
#include<set>
#include<map>

#define L(x) (x<<1)
#define R(x) (x<<1|1)
#define MID(x,y) ((x+y)>>1)

#define bug printf("hihi\n")

#define eps 1e-8

typedef long long ll;

using namespace std;

#define N 35

int dp[33][15][33];

int degree,k;
int bit[N];

int dfs(int pos,int degree,int t,bool bound)
{
     if(t<0) return 0;
     if(pos==0) return t ? 0:1;
     if(!bound&&dp[pos][degree][t]>=0) return dp[pos][degree][t];
     int up=bound ? min(bit[pos],1):1;
     int ans=0;
     for(int i=0;i<=up;i++)
        ans+=dfs(pos-1,degree,t-i,bound&&i==bit[pos]); //必须是bit[pos],不能是uo
     if(!bound) dp[pos][degree][t]=ans;
     return ans;
}

int solve(int x)
{
    int i,j;
    int len=0;
    while(x)
    {
        bit[++len]=x%degree;
        x/=degree;
    }
    return dfs(len,degree,k,true);
}

int main()
{
    int i,j,le,ri;
    memset(dp,-1,sizeof(dp));

    while(~scanf("%d%d",&le,&ri))
    {
        scanf("%d%d",&k,°ree);
        printf("%d\n",solve(ri)-solve(le-1));
    }
   return 0;
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-10-10 17:06:38

Timus Online Judge 1057. Amount of Degrees(数位dp)的相关文章

ural 1057. Amount of Degrees 数位dp

题目链接 给四个数l, r, k, b. 求出在[l, r]内满足这个数可以分解成k个不同的b次方的数的个数. 只要把一个数按b进制分解, 然后找一个刚好有k个1, 其余都是0的数的个数. 好神....按B进制分解完全想不到. 1 #include<bits/stdc++.h> 2 using namespace std; 3 #define pb(x) push_back(x) 4 #define ll long long 5 #define mk(x, y) make_pair(x, y)

[ACM] ural 1057 Amount of degrees (数位统计)

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 exactlyK different integer degrees of B. Example. Let X=15, Y=20, K=2, B=2. By this exampl

URAL - 1057 Amount of Degrees

Description 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 degre

Ural 1057 Amount of Degrees(数位DP)

题目链接:点击打开链接 题目大意:求给定区间[X,Y]中满足下列条件的整数个数:这个数恰好等于K个互不相等的B的整数次幂之和.例如,设X=15,Y=20,K=2,B=2,则有且仅有下列三个数满足题意:17 = 2^4+2^0, 18 = 2^4+2^1, 20 = 2^4+2^2. 1 ≤ X ≤ Y ≤ 2^31?1,1 ≤ K ≤ 20,  2 ≤ B ≤ 10. 思路:数位DP的思想, 因为本题满足区间减法, 所以我们只需要求出一个不大于n的满足要求的数的个数,那么先预处理出一个B进制数列

ural 1057 Amount of degrees 题解

题目大意:统计区间[x,y]中在b进制下含k个1的数字个数. 数位dp. 具体见2009刘聪论文<浅谈数位类统计问题>... 1 #include<cstdio> 2 const int MAXN=32; 3 int f[MAXN][MAXN]; 4 void init() 5 { 6 f[0][0]=1; 7 for(int i=1;i<MAXN;++i) 8 { 9 f[i][0]=f[i-1][0]; 10 for(int j=1;j<=i;++j) 11 f[i

URAL 1057 Amount of Degrees(数位统计)

题意:  求给定区间[X,Y]中满足下列条件的整数个数:这个数恰好等于K 个互不相等的B的整 数次幂之和. 思路:对于二进制来说(图片摘自刘聪的浅谈数位类统计问题论文) 现在推广到b进制 因为对于b进制的每一位,我们只需要讨论这一位是否是一,所以我们可以把这个数转换为一个等价的二进制数, 方法是将这个数从左到右第一位不是零或一的位变为1,并把其右边的所有位置一,求出这个二进制数. #include<cstdio> #include<cstring> #include<cm

URAL 1057 Amount of Degrees (数位DP,入门)

题意: 求给定区间[X,Y]中满足下列条件的整数个数:这个数恰好等于K个互不相等的,B的整数次幂之和.例如,设X=15,Y=20,K=2,B=2,则有且仅有下列三个数满足了要求:  17 = 24+20, 18 = 24+21, 20 = 24+22.(以B为底数,幂次数不允许相同) 参考论文-->>论文中的题. 思路: 论文倒是容易看明白,但是这个转成B进制的思想一直转不过来.其实转成B进制后变成 a1*Bn+a2*Bn-1...an*B0.其中ai是系数.范围是[0,B-1].但是看了论文

ural 1057 Amount of degrees 【数位dp】

题意:求(x--y)区间转化为 c 进制 1 的个数为 k 的数的出现次数. 分析:发现其满足区间减法,所以可以求直接求0---x 的转化为 c 进制中 1 的个数为k的数的出现次数. 首先用一个数组f[i][j]:表示前 i 位中有 j 位为 1 的个数. 可以通过方程 f[i][j] = f[i-1][j] + f[i-1][j-1]来预处理出来. 对于要求的答案,我们可以借助树来求. 假如13 ,2进制,有3个1 ,转化为2进制 1101 可以借助于一个二进制的表示的树来求. AC代码:

[数位dp] ural 1057 Amount of Degrees

题意:x.y.k.b.在[x,y]范围内的b进制数能分成k个b进制位权和的数有多少个. 思路: dp[site][n][k][b] n就代表已经分成了几个. 其实就是把数转换成对应的进制 然后这时候len不再是原来的那么简单. 应该是如果是边界的话取  当前位和1的最小值 不是的话 就取1 因为这位上有数说明这位可以被分走 所以这位上的数多少他都是1 然后就是判断是否是边界 要判断到是不是等于这个位上的数 而不是等于len. 代码: #include"cstdlib" #include