https://www.lydsy.com/JudgeOnline/problem.php?id=2425
https://www.luogu.org/problemnew/show/P2518
You have a set of non-zero numbers (not necessarily unique) into which you can insert any number of 0s, which results in an infinite number. For example, given {1,2}, the numbers 12, 21, 102, 120, 201, 210, 1002, 1020, etc. can be generated.
Now given a number, ask how many numbers come before this number. (Note that this number will not have leading zeros).
After reading the question for a long time, I finally understood it.
We enumerate numbers smaller than the current bit from high to low, and then arrange all the remaining elements behind.
The full array of reusable elements = the number of elements! /Number of each element! product of .
To prevent explosions, the numerator and denominator can be decomposed and then calculated.
(It seems that it is essentially a very violent and somewhat thinking water problem, not a digital dp)
#include<cstdio> #include<iostream> #include<vector> #include<queue> #include<cstring> #include<algorithm> using namespace std; typedef long long ll; const int N=51; inline int read(){ int X=0,w=0;char ch=0; while(!isdigit(ch)){w|=ch=='-';ch=getchar();} while(isdigit(ch))X=(X<<3)+(X<<1)+(ch^48),ch=getchar(); return w?-X:X; } char s[N]; int n,sum,t[11],p[N]; ll ans=0; int main(){ cin>>s+1; n=strlen(s+1); for(int i=1;i<=n;i++)t[s[i]-'0']++,sum++; for(int i=1;i<=n;i++){ for(int j=0;j<s[i]-'0';j++){ if(t[j]){ memset(p,0,sizeof(p)); t[j]--;sum--; for(int k=0;k<=9;k++) for(int l=2;l<=t[k];l++) p[l]++; ll tmp=1; for(int k=2;k<=sum;k++){ tmp*=k; for(int l=2;l<N;l++){ while(p[l]&&tmp%l==0){ p[l]--;tmp/=l; } } } ans+=tmp; t[j]++;sum++; } } t[s[i]-'0']--,sum--; } printf("%lld\n",ans); return 0; }
+++++++++++++++++++++++++++++++++++++++++++
+ Author of this article: luyouqi233. +
+Welcome to my blog: http://www.cnblogs.com/luyouqi233/ +
+++++++++++++++++++++++++++++++++++++++++++