论文里面的题目,感觉如果用二叉树来解释$DP$的过程很好理解...
题目:
分析:
代码:
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
//by NeighThorn
using namespace std;
const int maxn=31+5;
int n,m,k,b,f[maxn][maxn],bit[2][maxn];
inline int calc(int x,int k){
int cnt=0,ans=0;
for(int i=31;i>=1;i--){
if((x>>i)&1){
cnt++;
if(cnt>k) break;
x=x^(1<<i);
}
if((1<<(i-1))<=x)
ans+=f[i-1][k-cnt];
}
if(cnt+x==k) ans++;
return ans;
}
signed main(void){
scanf("%d%d%d%d",&n,&m,&k,&b);
f[0][0]=1;n--;
for(int i=1;i<=31;i++){
f[i][0]=1;
for(int j=1;j<=i;j++)
f[i][j]=f[i-1][j]+f[i-1][j-1];
}
if(b!=2){
while(n)
bit[0][++bit[0][0]]=n%b,n/=b;
while(m)
bit[1][++bit[1][0]]=m%b,m/=b;
int Bit=-1;
for(int i=bit[0][0];i>=1;i--)
if(bit[0][i]!=0&&bit[0][i]!=1){
Bit=i;break;
}
if(Bit!=-1)
for(int i=Bit;i>=1;i--)
bit[0][i]=1;
Bit=-1;
for(int i=bit[1][0];i>=1;i--)
if(bit[1][i]!=0&&bit[1][i]!=1){
Bit=i;break;
}
if(Bit!=-1)
for(int i=Bit;i>=1;i--)
bit[1][i]=1;
for(int i=bit[0][0];i>=1;i--)
n=(n<<1)|bit[0][i];
for(int i=bit[1][0];i>=1;i--)
m=(m<<1)|bit[1][i];
}
printf("%d\n",calc(m,k)-calc(n,k));
return 0;
}
By NeighThorn