zhber 有好多做过的题没写下来，如果我还能记得就补吧

## Input

* Line 1: 两个用空格分开的整数，分别表示Start 和 Finish。

## Output

* Line 1: Start..Finish范围内round numbers的个数

2 12

## Sample Output

6

2 10 1x0 + 1x1 ROUND
3 11 0x0 + 2x1 NOT round
4 100 2x0 + 1x1 ROUND
5 101 1x0 + 2x1 NOT round
6 110 1x0 + 2x1 NOT round
7 111 0x0 + 3x1 NOT round
8 1000 3x0 + 1x1 ROUND
9 1001 2x0 + 2x1 ROUND
10 1010 2x0 + 2x1 ROUND
11 1011 1x0 + 3x1 NOT round
12 1100 2x0 + 2x1 ROUND

f[i][j][k]表示长度为i有j个0k个1的round number个数，其实j+k=i，冗余了

#include<cstdio>
#include<cstring>
int f[50][50][50];
int s[50];
int l,r,len,ans;
inline int dfs(int now,int x1,int x2,bool work,bool first)
{
if(!now)
{
if(first)return 1;
if(x1>=x2)return 1;
return 0;
}
if(!first&&!work&&f[now][x1][x2]!=-1)return f[now][x1][x2];
int last;if(work)last=s[now];else last=1;
int tot=0;
for(int i=0;i<=last;i++)
{
if(first)
{
if(!i)tot+=dfs(now-1,0,0,work&&last==i,1);
else tot+=dfs(now-1,x1,x2+1,work&&last==i,0);
}else
{
if(!i)tot+=dfs(now-1,x1+1,x2,work&&last==i,0);
else tot+=dfs(now-1,x1,x2+1,work&&last==i,0);
}
}
if(!work&&!first)f[now][x1][x2]=tot;
}
inline int calc(int n)
{
len=0;
while(n)
{
s[++len]=n&1;
n/=2;
}
ans=dfs(len,0,0,1,1);
return ans;
}
int main()
{
while(scanf("%d%d",&l,&r)!=EOF)
{
memset(f,-1,sizeof(f));
printf("%d\n",calc(r)-calc(l-1));
}
}

posted on 2014-08-01 23:11  zhber  阅读(182)  评论(0编辑  收藏  举报