根数位DP思想差不多,但是根本不用DP……
先枚举不到n位的,组合数算算,然后还是从高位到低位逐位确定,组合数算算就行了
组合数算算嘛……就是你确定一下最高位,然后剩下的可以随意摆放,就是阶乘,然后再除以每个数字个数的阶乘就行了
额,这好像不是组合数啊-_-
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<ctime>
#include<cmath>
#include<algorithm>
#include<iomanip>
#include<vector>
#include<map>
#include<set>
#include<bitset>
#include<queue>
#include<stack>
using namespace std;
#define MAXN 1010
#define MAXM 1010
#define INF 1000000000
#define MOD 1000000007
#define eps 1e-8
#define ll long long
struct data{
int a[10];
data(){
memset(a,0,sizeof(a));
}
};
data ch(data x,int y,int z){
x.a[y]+=z;
return x;
}
char s[MAXN];
int n,m;
ll ans;
data now;
int t[MAXN];
void ADD(int x,int y){
int i;
for(i=2;x!=1;i++){
while(!(x%i)){
t[i]+=y;
x/=i;
}
}
}
void add(int x,int y){
int i,j;
for(i=2;i<=x;i++){
ADD(i,y);
}
}
ll cal(data x,int y){
int i,j;
if(!x.a[y]){
return 0;
}
memset(t,0,sizeof(t));
int N=0;
for(i=0;i<=9;i++){
N+=x.a[i];
}
add(N-1,1);
ADD(x.a[y],1);
for(i=0;i<=9;i++){
add(x.a[i],-1);
}
ll re=1;
for(i=1;i<=50;i++){
for(j=1;j<=t[i];j++){
re*=i;
}
}
return re;
}
int main(){
int i,j;
scanf("%s",s+1);
n=strlen(s+1);
for(i=1;i<=n;i++){
s[i]-='0';
if(s[i]){
m++;
now=ch(now,s[i],1);
}
}
for(i=1;i<=n/2;i++){
swap(s[i],s[n-i+1]);
}
for(i=m;i<n;i++){
for(j=1;j<=9;j++){
ans+=cal(ch(now,0,i-m),j);
}
}
now=ch(now,0,n-m);
for(j=1;j<s[n];j++){
ans+=cal(now,j);
}
now=ch(now,s[n],-1);
for(i=n-1;i;i--){
for(j=0;j<s[i];j++){
ans+=cal(now,j);
}
now=ch(now,s[i],-1);
}
printf("%lld\n",ans);
return 0;
}
/*
1020
*/