1. 程式人生 > >POJ 3252 區間內一個數的二進位制中0的數量要不能少於1的數量(數位DP)

POJ 3252 區間內一個數的二進位制中0的數量要不能少於1的數量(數位DP)

題意:求區間內二進位制中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; }
View Code