重新学习数位DP。。
有一个思路,枚举全排列,然后看看比当前数小的有多少个
当然肯定是不行的啦
但是我们可以用排列组合的知识求出全排列的个数
考虑数位dp
套用数位dp的方法,枚举每一位,然后后面的数用排列组合求出方案数。
具体还是看代码吧。。说起来真不好说。。
#include <cstdio>
#include <cstring>
#include <iostream>
#define N 1001
#define LL long long
using namespace std;
int n, m;
int d[101], num[10];
char c[N];
LL f[N][N], t, ans;
inline LL C(int x, int y)
{
if(f[x][y]) return f[x][y];
if(y > x) return 0;
if(y == 1) return f[x][y] = x;
if(y == 0 || y == x) return f[x][y] = 1;
return f[x][y] = C(x - 1, y) + C(x - 1, y - 1);
}
int main()
{
int i, j, k;
scanf("%s", c + 1);
n = strlen(c + 1);
for(i = n; i >= 1; i--)
{
d[i] = c[n - i + 1] - '0';
num[d[i]]++;
}
for(i = n; i >= 1; i--)
{
for(j = 0; j < d[i]; j++)
if(num[j])
{
m = i - 1;
t = 1;
num[j]--;
for(k = 0; k <= 9; k++)
t *= C(m, num[k]), m -= num[k];
ans += t;
num[j]++;
}
num[d[i]]--;
}
cout << ans << endl;
return 0;
}