Ural 1057. Amount of Degrees
论文里面的题目,感觉如果用二叉树来解释$DP$的过程很好理解...
题目:
分析:
代码:
#include<algorithm> #include<iostream> #include<cstring> #include<cstdio> //by NeighThorn using namespace std; const int maxn=31+5; int n,m,k,b,f[maxn][maxn],bit[2][maxn]; inline int calc(int x,int k){ int cnt=0,ans=0; for(int i=31;i>=1;i--){ if((x>>i)&1){ cnt++; if(cnt>k) break; x=x^(1<<i); } if((1<<(i-1))<=x) ans+=f[i-1][k-cnt]; } if(cnt+x==k) ans++; return ans; } signed main(void){ scanf("%d%d%d%d",&n,&m,&k,&b); f[0][0]=1;n--; for(int i=1;i<=31;i++){ f[i][0]=1; for(int j=1;j<=i;j++) f[i][j]=f[i-1][j]+f[i-1][j-1]; } if(b!=2){ while(n) bit[0][++bit[0][0]]=n%b,n/=b; while(m) bit[1][++bit[1][0]]=m%b,m/=b; int Bit=-1; for(int i=bit[0][0];i>=1;i--) if(bit[0][i]!=0&&bit[0][i]!=1){ Bit=i;break; } if(Bit!=-1) for(int i=Bit;i>=1;i--) bit[0][i]=1; Bit=-1; for(int i=bit[1][0];i>=1;i--) if(bit[1][i]!=0&&bit[1][i]!=1){ Bit=i;break; } if(Bit!=-1) for(int i=Bit;i>=1;i--) bit[1][i]=1; for(int i=bit[0][0];i>=1;i--) n=(n<<1)|bit[0][i]; for(int i=bit[1][0];i>=1;i--) m=(m<<1)|bit[1][i]; } printf("%d\n",calc(m,k)-calc(n,k)); return 0; }
By NeighThorn