數位dp初學2
阿新 • • 發佈:2021-12-11
洛谷
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)returncnt0>=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 } 16if(!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