题目大意:
一个数字把他看成二进制数字,数字里又会一些相邻的1,问从0到n至间所有相邻1的总和是多少?
分解成2进制数字,然后数位DP就行了。
========================================================================
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #include<cmath> #include<queue> #include<vector> #include<map> using namespace std; typedef long long LL; const int INF = 1e9+7; const int MAXN = 255; int bit[40];///dp[位数][首位是否是1] LL dp[40][60][2]; LL DFS(int pos,int num,bool Is1,int Lim)///num代表这个数字里面成对的 { if(pos == -1) return num; if(dp[pos][num][Is1] != -1 && !Lim) return dp[pos][num][Is1]; int end = Lim?bit[pos]:1; LL ans = 0, k = 0; for(int i=0; i<=end; i++) { if(i == 1 && Is1) k = 1; ans += DFS(pos-1, num+k, i==1, Lim && i==end); } if(!Lim) dp[pos][num][Is1] = ans; return ans; } LL solve(int n) { int len = 0; while(n) { bit[len++] = n%2; n /= 2; } return DFS(len-1, 0, false, true); } int main() { int T, cas = 1, n; memset(dp, -1, sizeof(dp)); scanf("%d", &T); while(T --) { scanf("%d", &n); printf("Case %d: %lld ",cas++, solve(n)); } return 0; }