2的k次方进制数
一个2k进制数
一个2k进制数从左到右每一位上的数分别表示20*k,21*k,22*k,……
转换为2进制后分别对应着0k-1,k2k-1,2k~3k
因为“r 的每一位严格小于它右边相邻的那一位”所以选出一些数来它们的排序方式是确定的,求组合数
#include<bits/stdc++.h>
using namespace std;
string f[600][600];
int aa[300],bb[300],cc[300];
string sum(string a,string b)
{
memset(cc,0,sizeof(cc));
memset(aa,0,sizeof(aa));
memset(bb,0,sizeof(bb));
int la=a.size(),lb=b.size(),lc=1,x=0;
string c="\0";
for(int i=0;i<la;i++) aa[la-i]=a[i]-'0';
for(int i=0;i<lb;i++) bb[lb-i]=b[i]-'0';
while(lc<=la||lc<=lb)
{
cc[lc]=aa[lc]+bb[lc]+x;
x=0;
if(cc[lc]>9) cc[lc]=cc[lc]%10,x=1;
lc++;
}
lc--;
if(x==1) cc[++lc]=1;
for(int i=0;i<lc;i++)
{
c+=(char)cc[lc-i]+'0';
}
return c;
}
int main()
{
int k,w;
string ans="0";
cin>>k>>w;
int k2=1<<k,n=w/k;
f[0][0]="1";
for(int i=1;i<=k2;i++)
f[i][0]=f[i][i]="1";
for(int i=1;i<k2;i++)
for(int j=1;j<i;j++)
f[i][j]=sum(f[i-1][j],f[i-1][j-1]);
int minn=min(k2-1,n);
for(int i=2;i<=minn;i++)
ans=sum(ans,f[k2-1][i]);
if(w%k)
{
int lim=(1<<(w%k))-1;
for(int i=1;i<=lim;i++)
{
if(n>k2-1-i)
break;
ans=sum(ans,f[k2-i-1][n]);
}
}
cout<<ans;
return 0;
}