[bzoj1662] [Usaco2006 Nov]Round Numbers 圆环数
第一眼:这好像是数位DP?
然后看了下来源......银组题?...肯定是我想多了
妈呀银组题竟然出数位DP....
处理出f[i][j]表示i位,0比1至少多j个的方案数。
但因为涉及负数什么的。。所以预处理一下组合数,每次用到的时候再强行枚举算出来。。
1 #include<cstdio> 2 #include<iostream> 3 #include<cstring> 4 #include<algorithm> 5 using namespace std; 6 int c[35][35],s[35]; 7 int i,j,k,n,m; 8 9 inline int get(int x,int y){//x位中,0比1多至少y个 10 int i,sm=0; 11 for(i=0;i<=x;i++)if(i>=x-i+y)sm+=c[x][i]; 12 return sm; 13 } 14 inline int get(int x){ 15 if(!x)return 0; 16 int i,len=0,tmp=x,more=0,ans=0; 17 while(tmp)s[++len]=tmp&1,tmp>>=1; 18 for(i=1;i<len;i++)ans+=get(i-1,1); 19 more=1,len--; 20 while(len){ 21 if(s[len]==1) 22 ans+=get(len-1,more-1); 23 more+=s[len]?1:-1,len--; 24 } 25 ans+=more<=0;return ans; 26 } 27 int main(){ 28 for(i=0;i<33;i++)c[i][0]=1; 29 for(i=1;i<=33;i++)for(j=1;j<=i;j++)c[i][j]=c[i-1][j]+c[i-1][j-1]; 30 scanf("%d%d",&n,&m); 31 printf("%d\n",get(m)-get(n-1)); 32 }