题意:求出区间内二进制表示是0的个数不小于1的个数的数的个数。
解题关键:数位dp,记忆化搜索的写法。
如果设一个三维数组,则不需要!lead。
#include<cstdio> #include<cstring> #include<algorithm> #include<cstdlib> #include<iostream> #include<cmath> using namespace std; typedef long long ll; int dp[35][66]; int a[35]; int dfs(int pos,int sta,bool lead,bool limit){ if(pos==-1) return sta>=32; if(!limit&&!lead&&dp[pos][sta]!=-1) return dp[pos][sta]; int up=limit?a[pos]:1,ans=0; for(int i=0;i<=up;i++){ int t=lead&&i==0; ans+=dfs(pos-1,t?sta:sta+(i==0?1:-1),t,limit&&i==a[pos]); } if(!limit&&!lead) dp[pos][sta]=ans; //!lead? return ans; } int solve(int x){ int pos=0; while(x){ a[pos++]=x&1; x>>=1; } return dfs(pos-1,32,true,true); } int main(){ memset(dp,-1,sizeof dp); int a,b; while(~scanf("%d%d",&a,&b)){ printf("%d ",solve(b)-solve(a-1)); } return 0; }