重新学习数位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; }