Problem Description
让你求区间范围内round number的个数
round number:就是把一个十进制数转换为一个二进制数,若该二进制数中0的个数大于等于1的个数,就是round number
思路:
我们记忆化搜索的时候,只需要记录0的个数 和 1的个数,然后0的个数大于1的个数即可。
我们还可以更巧妙点 设一个数初始化位0 遇到0的时候++,遇到1的时候–。如果最后这个数大于-1的话。那么就是round number
#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
#define ll long long
int a[60], dp[60][120][2];
int len;
ll dfs(int pos, int num, int sta, int limit)//num 可能是负数
{
// printf("%d %d %d\n", pos, num, (len+1)/2);
if(pos < 0) return num >= 0;
if(!limit && dp[pos][num+60][sta] != -1) return dp[pos][num+60][sta];
int up = limit ? a[pos] : 1;
ll res = 0;
for(int i = 0; i <= up; i++)
{
if(sta) res += dfs(pos-1, i?num-1:num+1, sta, limit && i == a[pos]);
else
res += dfs(pos-1, (i==1)?num-1:0, i==1, limit && i == a[pos]);
}
if(!limit) dp[pos][num+60][sta] = res;
return res;
}
ll solve(ll x)
{
int pos = 0;
while(x)
{
a[pos++] = x%2;
x /= 2;
}
len = pos;
return dfs(pos-1, 0, 0, 1);
}
int main()
{
ll lt, rt;
memset(dp, -1, sizeof(dp));
while(cin >> lt >> rt)
{
// cout << solve(rt) << ' ' << solve(lt-1) << endl;
cout << solve(rt) - solve(lt-1) << endl;
}
return 0;
}