POJ3252 Round Numbers(数位dp)
这里只需先转化乘二进制后,记录前面有几个0和几个1,并且记录前导0状态,因为前导0会影响答案
#include<iostream> #include<algorithm> #include<cstring> #include<cstdio> #include<map> #include<string> #include<vector> using namespace std; typedef long long ll; const int N=1e6+10; int l,r; vector<int> num; int len; int f[33][33][33][2][2]; int dfs(int cur,int p1,int p2,int flag,int g){ if(cur==len) return p1>=p2; if(f[cur][p1][p2][flag][g]!=-1) return f[cur][p1][p2][flag][g]; int v=1; if(flag) v=num[cur]; int ans=0; int i; for(i=0;i<=v;i++){ if(g){ if(!i) ans+=dfs(cur+1,p1,p2,flag&&(i==v),1); else{ ans+=dfs(cur+1,p1,p2+1,flag&&(i==v),0); } } else{ ans+=dfs(cur+1,p1+(i==0),p2+(i==1),flag&&(i==v),0); } } return f[cur][p1][p2][flag][g]=ans; } int solve(int t){ num.clear(); int i; memset(f,-1,sizeof f); while(t){ num.push_back(t%2); t/=2; } len=(int)num.size(); reverse(num.begin(),num.end()); return dfs(0,0,0,1,1); } int main(){ while(cin>>l>>r) cout<<solve(r)-solve(l-1)<<endl; return 0; }
没有人不辛苦,只有人不喊疼