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 }