POJ - 3252

题意:数字[L,R]中,round number数字的个数。round number即数字转换成二进制后0的个数大于等于1的个数。

总结:dp[l][cnt0][cnt1][zero]表示还剩l位,先有cnt0个0,cnt1个1,是否是前导0

#include <bits/stdc++.h>

using namespace std;
const int maxn = 64;
#define ll long long

ll dp[maxn][maxn / 2][maxn / 2][2], tot, dight[maxn];

ll dfs(int l, int cnt0, int cnt1, bool zero, bool sig) {
	if(l == 0) return cnt0 >= cnt1;
	if(!sig && dp[l][cnt0][cnt1][zero] != -1) return dp[l][cnt0][cnt1][zero];
	int nex = sig ?dight[l] :1; ll res = 0;
	for (int i = 0; i <= nex; ++i) {
		res += dfs(l - 1, zero ?0 :cnt0 + (i == 0), cnt1 + (i == 1), zero && (i == 0), sig && (i == nex));
	}
	if(!sig) dp[l][cnt0][cnt1][zero] = 1;
	return res;
}
ll calc(ll a) {
	tot = 0;
	while(a) {
		dight[++tot] = a % 2; a >>= 1;
	}
	return dfs(tot, 0, 0, 1, 1);
}
int main() {
	memset(dp, -1, sizeof dp);
	ll l, r; scanf("%lld%lld", &l, &r);
	printf("%lld\n", calc(r) - calc(l - 1));
}

  

猜你喜欢

转载自www.cnblogs.com/oi-forever/p/9126149.html
今日推荐