题意:求区间内二进制中0的数量要不能少于1的数量
分析:很明显的是数位DP;
菜鸟me : 整体上是和数位dp模板差不多的 , 需要注意的是这里有前导零的影响 , 所以需要在dfs()里面增加zor 变量的限制条件 ,
那么我们的dp[i][j] 是表示第i 位置 , ,0的数量减去1的数量不少于 j 的方案数 , 那剩下的就简单了咯 ,哦还需要注意的是 这里的 j 会出现负数的情况 , 那也很好解决咯 ,偏移下就好拉 , 从32开始 ,也就是说32表示0
#include<stdio.h> #include<string.h> int dp[40][70]; int a[70]; int dfs(int pos , int sta , int limit , int zor) { if(pos==-1) return sta>=32; if(!limit && !zor && dp[pos][sta]!=-1) return dp[pos][sta]; int up=limit?a[pos]:1; int ans=0; for(int i=0 ; i<=up ; i++) { if(zor && i==0) ans+=dfs(pos-1,sta,limit&&i==a[pos],zor&&i==0); else { if(i==0) ans+=dfs(pos-1,sta+1,limit&&i==a[pos],zor&&i==0); else ans+=dfs(pos-1,sta-1,limit&&i==a[pos],zor&&i==0); } } if(!limit && !zor) dp[pos][sta]=ans; return ans; } int so(int x) { int ans=0; while(x) { a[ans++]=x%2; x/=2; } return dfs(ans-1,32,1,1); } int main( ) { int l,r; memset(dp,-1,sizeof(dp)); while(scanf("%d%d",&l,&r)!=EOF) { printf("%d\n",so(r)-so(l-1)); } return 0; }
原文地址:https://www.cnblogs.com/shuaihui520/p/9919327.html
时间: 2024-08-03 19:32:57