[数位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"cstdio"
#include"cstring"
#include"cmath"
#include"queue"
#include"algorithm"
#include"iostream"
using namespace std;
//2014年9月24日19:51:00
int dp[35][22][22][12];
int num[35];
int dfs(int site,int n,int k,int m,int f)
{
    if(site==0) return n==k;
    if(!f&&~dp[site][n][k][m]) return dp[site][n][k][m];
    int len=f?min(num[site],1):1;
    int ans=0;
    for(int i=0;i<=len;i++)
    {
        if(i) ans+=dfs(site-1,n+1,k,m,f&&i==num[site]);
        else ans+=dfs(site-1,n,k,m,f&&i==num[site]);
    }
    if(!f) dp[site][n][k][m]=ans;
    return ans;
}
int solve(int x,int k,int m)
{
    int cnt=0;
    while(x)
    {
        num[++cnt]=x%m;
        x/=m;
    }
    return dfs(cnt,0,k,m,1);
}
int main()
{
    int x,y,k,m;
    memset(dp,-1,sizeof(dp));
    while(scanf("%d%d%d%d",&x,&y,&k,&m)!=-1)
    {
        printf("%d\n",solve(y,k,m)-solve(x-1,k,m));
    }
    return 0;
}
//2014年9月24日19:58:31
时间: 2024-10-19 14:01:09

[数位dp] ural 1057 Amount of Degrees的相关文章

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

[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(数位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 数位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)

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代码:

URAL 1057 Amount of Degrees(数位统计)

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

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 exampl