[HDU3252] [USACO06Nov,Silver] Round Number [数位dp]

[ L i n k \frak{Link} ]


询问[a,b]内二进制表示中0的个数不小于1的个数的整数数量。
显然是数位dp
最大的b30位。当1的数量超过b的位数的一半的时候就无解了。
注意处理好前导0

小心不要给数组下标为负的地方存东西。。


#include<cstdio>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<cctype>
using namespace std;
int n,m;
int bit[35];
int F[35][70]; 
int dfs(int pos, int state, bool lead, bool limit) {
	if(!pos) return state >= 35;
	if(!lead && !limit && F[pos][state] != -1) return F[pos][state];
	int ret = 0, up = limit ? bit[pos] : 1;
	for(int i = 0; i <= up; ++i) {
		ret += dfs(pos - 1, state + ( (i == 1) ? -1 : (lead ? 0 : 1) ), lead && i == 0, limit && i == up);
	}
	if(!lead && !limit) F[pos][state] = ret;
	return ret;
}
int solve(int x) {
	bit[0] = 0;
	while(x) {
		bit[++bit[0]] = x & 1;
		x >>= 1;
	}
	return dfs(bit[0], 35, true, true);
}
int main() {
	memset( F, -1, sizeof(F) );
	scanf("%d%d", &n, &m);
	printf( "%d", solve(m) - solve(n - 1) );
	return 0;
}

猜你喜欢

转载自blog.csdn.net/Estia_/article/details/83443087
今日推荐