Fast Bit Calculations LightOJ - 1032

Fast Bit Calculations LightOJ - 1032

题意:求0到n的所有数的二进制表示中,"11"的总数量。(如果有连续的n(n>2)个1,记(n-1)个"11")

方法:常规数位dp。ans[pos][ans][f][pre0],pos当前位置,ans当前答案,f前一位,pre0是否在前导0

记一下看到的奇怪的做法:http://www.cnblogs.com/WABoss/p/5127652.html

错误(本地):
注意:按这种模板来写数位dp,要求将答案也记录进状态,其含义是当前面产生的答案相同,其他条件相同时,后面产生的答案也相同。

 1 #include<cstdio>
 2 #include<cstring>
 3 typedef long long LL;
 4 LL w[40],T,TT,n;
 5 LL ans[40][40][2][2];
 6 LL dp(LL pos,LL f,bool pre0,bool limit,LL xx)
 7 {
 8     if(pos<1)    return pre0?0:xx;
 9     if(!limit&&ans[pos][xx][f][pre0]!=-1)
10         return ans[pos][xx][f][pre0];
11     LL i,res=0,end=limit?w[pos]:1;
12     for(i=0;i<=end;i++)
13         res+=dp(pos-1,i,pre0&&i==0,limit&&i==w[pos],xx+(i==1&&f==1));
14     return limit?res:ans[pos][xx][f][pre0]=res;
15 }
16 LL get(LL x)
17 {
18     LL i;
19     for(i=0;x>0;x/=2)    w[++i]=x%2;
20     return dp(i,0,1,1,0);
21 }
22 int main()
23 {
24     memset(ans,-1,sizeof(ans));
25     scanf("%lld",&T);
26     for(TT=1;TT<=T;TT++)
27     {
28         scanf("%lld",&n);
29         printf("Case %lld: %lld\n",TT,get(n));
30     }
31     return 0;
32 }
posted @ 2017-10-28 12:49  hehe_54321  阅读(173)  评论(0编辑  收藏  举报
AmazingCounters.com