URAL1057 Amount of Degrees

题意:给定x,y,K,B,要求找出在区间[x,y]内的正整数个数,使它们满足恰好由K个不同的某个B的幂组成

例如

X=15, Y=20, K=2, B=2

17 = 24+20,
18 = 24+21,
20 = 24+22. 有三个正整数满足要求

把问题转化一下,设g(x)为有多少个<=x的正整数满足题意,那么原题差分一下=g(y)-g(x-1)

现在解决转化之后的问题,把x进行B进制展开,目标是得到一个B进制串使它只含0和1,并且小于等于x,可以用动态规划来解决

用f[i][j][flag]表示进行到第i位,有j个1,flag=0,1分别表示小于,等于时的满足要求的总数,递推式容易得到,从高位到低位递推,注意细节。

最后答案为f[1][k][0]+f[1][k][1](这里1为最低位)

 1 #include <iostream>
 2 #include <cstring>
 3 using namespace std;
 4 int x,y,k,b;
 5 int len,Bbas[51];
 6 int f[51][21][2]; //1 等于 0 小于
 7 int solve(int p){
 8     len=0;memset(Bbas,0,sizeof(Bbas));
 9     memset(f,0,sizeof(f));
10     int t=p;
11     while (t){
12         Bbas[++len]=t%b;t=t/b;
13     }
14     if (Bbas[len]==1) {f[len][1][1]=1;f[len][0][0]=1;}
15         else {f[len][1][0]=1;f[len][0][0]=1;}
16     for (int i=len-1;i>=1;i--)
17         for (int j=0;j<=k;j++){
18             if (j==0) {
19                 f[i][j][0]=1;
20             }else {
21                 if (Bbas[i]>1) {
22                     f[i][j][0]=f[i+1][j-1][1]+f[i+1][j-1][0]+f[i+1][j][1]+f[i+1][j][0];
23                 }else {
24                     if (Bbas[i]==1) {
25                         f[i][j][0]=f[i+1][j][1]+f[i+1][j][0]+f[i+1][j-1][0];
26                         f[i][j][1]=f[i+1][j-1][1];
27                     }
28                     if (Bbas[i]==0) {
29                         f[i][j][0]=f[i+1][j][0]+f[i+1][j-1][0];
30                         f[i][j][1]=f[i+1][j][1];
31                     }
32                 }
33             }
34     }
35     return f[1][k][0]+f[1][k][1];
36 }
37 int main(){
38     cin>>x>>y>>k>>b;
39     cout<<solve(y)-solve(x-1)<<endl;
40     return 0;
41 }
时间: 2024-10-07 06:28:56

URAL1057 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

Ural Amount of Degrees(数位dp)

传送门 Amount of Degrees Time limit: 1.0 secondMemory limit: 64 MB 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 t

[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

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

一本通1585【例 1】Amount of Degrees

1585: [例 1]Amount of Degrees 时间限制: 1000 ms         内存限制: 524288 KB 题目描述 原题来自:NEERC 2000 Central Subregional,题面详见 Ural 1057. 求给定区间 [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 输入

Amount of Degrees

Amount of Degrees 题目描述 求给定区间\([X,Y]\)中满足下列条件的整数个数:这个数恰好等于\(K\)个互不相等的 的整数次幂之和.例如,设\(X=15, Y=20, K=2, B=2\) ,则有且仅有下列三个数满足题意: \(17 = 2^4+2^0\) \(18 = 2^4 + 2^1\) \(20 = 2^4+2^2\) 输入格式 第一行包含两个整数\(X\)和\(Y\),接下来两行包含整数\(K\)和\(B\). 输出格式 第一行包含两个整数 和 ,接下来两行包含整

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