P2518 [HAOI2010]计数
题目描述
你有一组非零数字(不一定唯一),你可以在其中插入任意个0,这样就可以产生无限个数。比如说给定{1,2},那么可以生成数字12,21,102,120,201,210,1002,1020,等等。
现在给定一个数,问在这个数之前有多少个数。(注意这个数不会有前导0).
输入输出格式
输入格式:
只有1行,为1个整数n.
输出格式:
只有整数,表示N之前出现的数的个数。
————————————————————————————————
题目都蛮难弄清楚的,涉及到可重集全排列,还有全排列的等价写法,还有一点简单计数,以及桶排,有意思
#include<bits/stdc++.h> using namespace std; int num[200],len,bol[90]; long long ans,cc[1001][1001],cnt; long long c(int a,int b){ if(cc[a][b])return cc[a][b]; if(a==1)return cc[a][b]=b; if(a==0||a==b) return cc[a][b]=1; if(a>b) return 0; return cc[a][b]=c(a,b-1)+c(a-1,b-1); } int main() { char ch; while(cin>>ch) if(isdigit(ch))num[++len]=ch-48,bol[num[len]]++; int temp=len; for(int i=1;i<=len;i++) { temp--; for(int j=0;j<num[i];j++) if(bol[j]) { bol[j]--; long long ans=1; int m=temp; for(int i=0;i<=9;i++)if(bol[i])ans*=c(bol[i],m),m-=bol[i]; cnt+=ans; bol[j]++; } bol[num[i]]--; } cout<<cnt; }