题意:给一串数字,第一个数是Num的话,要使后面的数字组成Num个数,而且为不降的,将这Num个数分配到9个素因子上作为指数,问能组成多少个不同的数
解法:dfs一遍,看后面的数字能组成Num个不降数字的方法种数,及该种方法的不同数字的个数,然后这些方法加起来。具体见代码吧。
代码:
#include <iostream> #include <cstdio> #include <cstring> #include <cmath> #include <algorithm> #include <string> #define ll long long using namespace std; #define N 30017 int C,Num; string S; int c[10] = {1,9,36,84,126,126,84,36,9,1}; int cnt[12]; ll a[12]; int tot,len; ll Res; ll fac(int n) { ll res = 1LL; for(int i=n;i>=1;i--) res *= i; return res; } void calc() { ll res = fac(Num)*c[Num]; for(int i=0;i<tot;i++) res /= fac(cnt[i]); Res += res; } void check(int u,int v,int num) { if(num == Num && u == v) { calc(); return; } ll ans = 0; if(num == Num) return; if(S[u] == '0') return; for(int i=u;i<v;i++) { ans += 10LL*ans + S[i]-'0'; if(num == 0 || ans >= a[tot-1]) { if(ans == a[tot-1]) //重复 { cnt[tot-1]++; check(i+1,len,num+1); cnt[tot-1]--; } else //非重复,新建 { cnt[tot]++; a[tot++] = ans; check(i+1,len,num+1); cnt[tot-1]--; tot--; } } } } int main() { int t,i; scanf("%d",&t); while(t--) { cin>>S; Num = S[0]-'0'; len = S.length(); tot = 0; Res = 0; check(1,len,0); printf("%lld ",Res); } return 0; }