这个问题源于昨日的 CF E题。让我想了好久.
问题定义
给定每种数字( )的个数 ,问用完其中每种数字,组合成一个数,其中不包含前导0的数有多少个。
比如:
, 那他可以组合成:
120,102,210,201
解法1
如果包含前导0也算进去,那么就是一个简单的多重排列问题了,
同理我们可以先把不包含0的排列数算出来 : , 对于其中每个排列,设 仅需将 后面的 个数和 0排列就好,
所以最终解为:
解法2
解法2有点麻烦,就是可以直接计算包含0的情况,然后枚举所有前导0的个数,减去就好。
代码
LL cal_cnt(int *state){
LL n=0;
for(int i=1 ; i<10 ; ++i)n += state[i];
LL ret = fact[n];
for(int i=1 ; i<10 ; ++i)ret /=fact[state[i]];
LL tmp =1;
if(cnt[0]>0){
tmp = fact[n+state[0]-1]/fact[state[0]]/fact[n-1];
}
return ret*tmp;
}