POJ 3252 Round Numbers

解题思路:

1. d[i][j]表示需i位二进制表示且1的个数不大于j(首位为1)的数的总和

2. 对数a,假设其二进制需要i位表示

  a)求不大于a round Number总和 Line 6~8

  b)如果j位为1,假设目前为止总共已出现k个1,求解位数小于j位且1的个数不大于i/2-k的数总和 Line 9~13

好烂的代码
1 #include <iostream>
2  using namespace std;
3 unsigned int i,j,k,t,ans,s,l,m,n,d[32][32],temp[32];
4 inline int cal(int a)
5 {
6 for(t=s=1,ans=i=0;t<=a;t*=2,i++)
7 ans+=d[i][i/2];
8 if(i>1)ans++;
9 for(l=i/2,j=i-1,t/=4,s=1;j>0&&s<l;j--,t/=2)
10 if(a&t){
11 for(k=1;k<j;k++)ans+=(l-s>k?d[k][k]:d[k][l-s]);
12 ans++,s++;
13 }
14 return ans;
15 }
16 int main()
17 {
18 for (i=1;i<32;i++)
19 {
20 for(temp[i-1]=j=1;j<=i;j++)
21 d[i][j]+=temp[j-1],temp[j-1]+=d[i][j-1];
22 for(j=1;j<32;j++)d[i][j]+=d[i][j-1];
23 }
24 scanf("%d %d",&m,&n);
25 printf("%d\n", cal(n)-cal(m-1));
26 return 0;
27 }

 


posted on 2010-12-29 17:02  ltang  阅读(353)  评论(0编辑  收藏  举报

导航