hihoCoder 扩展二进制数

明天就要去实验室干活了。。。。下次再打题不知是何时。。。。

题目链接:

http://hihocoder.com/contest/hihointerview11/problem/2

这题不难,一开始想错了。。。。其实并不复杂,从低位到高位,逐个1处理。

我用了个简单dp。

 

先将n转化成二进制。

 

我们划分出每个1+x个0的情况(x可为0)。

对于单个模块假设有s0[i+1]种情况,在前一个模块退一个1的情况下有s1[i+1]中情况。(这是有规律的)

假设不进位的情况下情况数:dp[0][i]

进位的情况下情况数:dp[1][i]

 

这样得到转移方程:dp[0][i+1] = s0[i+1]*dp[0][i] + dp[1][i]

dp[1][i+1] = s1[i+1]*dp[0][i] + dp[1][i]

 

AC代码:

 1 #include <bits/stdc++.h>
 2 
 3 using namespace std;
 4 const int maxn = 50;
 5 
 6 int p[maxn];
 7 typedef long long int64;
 8 
 9 int64 dp[2][maxn];
10 
11 int main(void){
12       int n;
13       scanf("%d", &n);
14 
15       if(n == 0){
16             printf("1\n");
17       }else{
18             int cnt = 0;
19             while(n){
20                   p[cnt++] = n%2;
21                   n >>= 1;
22             }
23 
24             vector<int> v;
25             int t = 1;
26             for(int i = 0; i < cnt; ++i){
27                   if(p[i] == 0){
28                         t++;
29                   }else{
30                         v.push_back(t);
31                         t = 1;
32                   }
33             }
34             //cout << "haha" << endl;
35 
36             int sz = v.size();
37             int64 ans;
38             dp[0][0] = v[0], dp[1][0] = v[0]-1;
39             for(int i = 1; i < sz; ++i){
40                   dp[0][i] = v[i]*dp[0][i-1] + dp[1][i-1];
41                   dp[1][i] = (v[i]-1)*dp[0][i-1] + dp[1][i-1];
42             }
43             /*for(int i = 0; i < sz; ++i)
44                   cout << dp[0][i] << "   " << dp[1][i] << endl;*/
45             ans = dp[0][sz-1];
46 
47             printf("%lld\n", ans);
48       }
49 
50       return 0;
51 }
View Code

 

posted @ 2016-07-01 21:13  zhazhalovecoding  阅读(387)  评论(0编辑  收藏  举报