URAL1057_Amount Of Degrees

来源:互联网 发布:windows运行命令快捷键 编辑:程序博客网 时间:2024/05/17 23:06

题目链接:URAL1057


题意:区间【X,Y】内,有多少个数可以表示成K个不同的B的幂次方之和

如:K=2,B=2,3=2^0+2^1,5=2^2+2^0等


这个题是论文上的题:算法合集之《浅谈数位类统计问题》

其实归到数位DP不是很合适,因为数学推导推完了之后就是一个组合数的问题


详细分析见论文吧,不再赘述,说说我对代码的理解

#include<map>#include<set>#include<math.h>#include<time.h>#include<iostream>#include<cstdio>#include<queue>#include<stack>#include<stdio.h>#include<cstring>#include<string.h>#include<algorithm>#include<cstdlib>using namespace std;#define lson rt<<1,l,mid#define rson rt<<1|1,mid+1,r#define ll rt<<1#define rr rt<<1|1#define LL long long#define ULL unsigned long long#define maxn 50#define maxnum 1000050#define eps 1e-6#define input freopen("input.txt","r",stdin)#define output freopen("output.txt","w",stdout)int x,y,k,b,C[maxn][maxn];int digit[maxn];int calc(int x,int k,int b){int len=0,ans=0;while(x){digit[++len]=x%b;x/=b;}for(int i=len;i>=0;i--){if (digit[i]>1){//考虑这一位不取答案是C[i-1][K] //考虑这一位取,答案是C[i-1][K-1]//所有情况考完了,可以退出循环了 ans+=C[i-1][k]+C[i-1][k-1];break;}else if (digit[i]==1){//考虑这一位不取的情况 ans+=C[i-1][k];k--;}if (k<0) return ans;}return ans;}int main(){//input;C[0][0]=1;for(int i=1;i<=40;i++){C[i][0]=C[i-1][0];for(int j=1;j<=i;j++)C[i][j]=C[i-1][j]+C[i-1][j-1];}scanf("%d%d%d%d",&x,&y,&k,&b);cout<<calc(y+1,k,b)-calc(x-1+1,k,b)<<endl;return 0;}


1 0
原创粉丝点击