数位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的个数为cnt1个,0的个数为cnt0个,的圆数个数;
 4 int dp[32][32][32],a[32];
 5 int dfs(int eq,int dep,int cnt1,int cnt0)
 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         ret+=dfs(eq&&(i==a[dep]),dep-1,cnt1+(i==1),cnt1?cnt0+(i==0):0);
14     }
15     if(!eq) dp[dep][cnt1][cnt0]=ret;
16     return ret;
17 }
18 int work(int n)
19 {
20     int cnt=0;
21     memset(dp,-1,sizeof(dp));
22     for(;n;n/=2)a[++cnt]=n%2;
23     return dfs(1,cnt,0,0);
24 }
25 
26 int main()
27 {
28     int L,R;
29     scanf("%d%d",&L,&R);
30     printf("%d\n",work(R)-work(L-1));
31     return 0;
32  }

 

posted @ 2021-12-11 17:12  matt-11  阅读(43)  评论(0)    收藏  举报