1. 程式人生 > 其它 >數位dp初學2

數位dp初學2

洛谷

P6218 [USACO06NOV] Round Numbers S

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 //dp[dep][cnt1][cnt0];//表示1-n中考慮到第dep位1的個數為cnt,0的個數為cnt0個的個數;
 4 int dp[32][32][32],a[32];
 5 int dfs(int eq,int dep,int is0,int cnt1,int cnt0)//這裡要考慮前導0,因為我們是從高位到低位列舉,如果當前位還是前導0那麼0的個數是不納入範圍的;
 6 {
 7     if(!dep)return
cnt0>=cnt1; 8 if(!eq&&~dp[dep][cnt1][cnt0])return dp[dep][cnt1][cnt0]; 9 int mx=eq?a[dep]:1; 10 int ret=0; 11 for(int i=0;i<=mx;i++) 12 { 13 int tt=(cnt1+(i==1))||cnt1; 14 ret+=dfs(eq&&(i==a[dep]),dep-1,tt,cnt1+(i==1),tt?cnt0+(i==0):0); 15 } 16
if(!eq) dp[dep][cnt1][cnt0]=ret; 17 return ret; 18 } 19 int work(int n) 20 { 21 int cnt=0; 22 memset(dp,-1,sizeof(dp)); 23 for(;n;n/=2)a[++cnt]=n%2; 24 return dfs(1,cnt,1,0,0); 25 } 26 27 int main() 28 { 29 int L,R; 30 scanf("%d%d",&L,&R); 31 printf("%d\n",work(R)-work(L-1
)); 32 return 0; 33 } 34