POJ 3252 Round Numbers

题意:定义一种数,满足条件:二进制表示中0个数大于等于1的个数。求给定闭区间内有多少个这种数。


思路:数位DP,dp[pos][zero][one] 表示已知二进制中首位1在第one位上,目前有零个数zero,现在要考虑pos位置上放0或1的满足条件的数的个数。记忆化搜一下就好了。


代码:

/*
    First数位DP POJ 3252
*/
#include<string.h>
#include<stdio.h>

int dp[33][33][33];
char buf[33];

int dfs(int zero,int one,int pos,int flag)
{
	int ans=0;
	if(zero!=-1 && !flag && dp[pos][zero][one]!=-1)
		return dp[pos][zero][one];
	if(pos==0)
		return one-zero<=zero;
    int end=flag?buf[pos-1]:1;
	for(int i=0;i<=end;i++){
		if(i==1 && !one)
			ans+=dfs(pos-1,pos,pos-1,flag && i==end);
		else 
			ans+=dfs(zero-i,one,pos-1,flag && i==end);
	}
	if(one && !flag){
		dp[pos][zero][one]=ans;
	}
	return ans;
}

inline int change(int x,char buf[],int r)
{
	int i=0;
	while(x){
		buf[i++]=x%2;
		x/=2;
	}
	return i;
}

inline int f(int x)
{
	int one=0,zero=0,n;
	if(x==0) return 0;
	n=change(x,buf,2);
	return dfs(-1,0,n,1);
}

int main()
{	
	int l,r;
	memset(dp,-1,sizeof(dp));
	while(~scanf("%d %d",&l,&r)){
		printf("%d\n",f(r)-f(l-1));
	}
	return 0;
}



你可能感兴趣的:(dp,poj)