標籤:
題意:
統計區間[L,R]有多少個數,其二進位標記法中的0的個數不少於1的個數?(不允許首碼0)
思路:
狀態表示為 [當前第幾位][總位元][1的個數],最後判斷一下1的個數是否滿足條件,要注意前置0的問題,可以通過枚舉二進位的位元來解決。
1 //#include <bits/stdc++.h> 2 #include <iostream> 3 #include <cstdio> 4 #include <cstring> 5 #include <cmath> 6 #include <map> 7 #include <algorithm> 8 #include <vector> 9 #include <iostream>10 #define pii pair<int,int>11 #define INF 0x7f3f3f3f12 #define LL long long13 #define ULL unsigned long long14 using namespace std;15 const double PI = acos(-1.0);16 const int N=32;17 18 int f[N][N][N], bit[N];19 //[當前第幾位][總位元][1的個數]20 int dfs(int i,int up,int cnt,bool e)21 {22 if(i==0) return cnt*2<=up;23 if(!e && ~f[i][up][cnt]) return f[i][up][cnt];24 if(cnt*2>up) return 0;25 26 int ans=0;27 int d= i==up?1:0;28 int u= e? bit[i]: 1;29 for( ; d<=u; d++)30 {31 ans+=dfs(i-1,up,cnt+d,e&&d==u);32 }33 return e? ans: f[i][up][cnt]=ans;34 }35 36 int cal(int n)37 {38 if(n<=1) return 0;39 int len=0;40 while(n) //拆數41 {42 bit[++len]=(n&1);43 n>>=1;44 }45 int ans=0;46 for(int i=2; i<len; i++) ans+=dfs(i,i,0,false);47 ans+=dfs(len,len,0,true);48 return ans;49 }50 51 int main()52 {53 //freopen("input.txt","r",stdin);54 memset(f, -1, sizeof(f));55 int a, b;56 scanf("%d%d",&a,&b);57 printf("%d\n",cal(b)-cal(a-1) );58 59 return 0;60 }AC代碼
POJ 3252 Round Numbers (區間DP,基礎)