Ural 1057. Amount of Degrees

题目链接

论文里面的题目,感觉如果用二叉树来解释$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

posted @ 2017-04-06 17:09  NeighThorn  阅读(270)  评论(0编辑  收藏  举报