meaning of the title
Divide n numbers into several groups. The minimum number in each group cannot be more than the total number of elements in this group. Find the number of schemes. N<=2000.
Reflection
If we get a partition of n numbers, we can simply find out the number of schemes. After sorting it from large to small, let larger I be the number of numbers greater than or equal to I, b[i] be the size of group I, sum be the prefix sum of B, then for group I, its contribution is C(larger[b[i]]-sum[i-1],b[i]). At the same time, if there is c bi, then divide by c!.
Because it is only related to the minimum number and the number of the minimum number, Let f[i][j][k] be the number of the first I selected, the current minimum bi is j, and there are k bi. Only when k is 1, prefixes and optimizations can be used. When k is not 1, it is transferred from k-1 and divided by K. Complexity O(n^3).
Note that J * k < = I, only n^2logn useful States, can be directly opened dynamically.
Code
1 #include<bits/stdc++.h> 2 #define mod 998244353 3 using namespace std; 4 typedef long long int ll; 5 const int maxn=2E3+5; 6 int n,a[maxn],larger[maxn],b[maxn],top; 7 int ans,fac[maxn],invC[maxn],sum[maxn][maxn],inv[maxn]; 8 int*f[maxn][maxn]; 9 int C[maxn][maxn]; 10 ll qpow(ll x,ll y) 11 { 12 ll base=x,ans=1; 13 while(y) 14 { 15 if(y&1) 16 ans=ans*base%mod; 17 base=base*base%mod; 18 y>>=1; 19 } 20 return ans; 21 } 22 inline void add(int&x,int y) 23 { 24 ll g=(ll)x+(ll)y; 25 if(g>=mod) 26 g-=mod; 27 x=g; 28 } 29 void init() 30 { 31 fac[0]=1; 32 for(int i=1;i<=n;++i) 33 fac[i]=(ll)fac[i-1]*(ll)i%mod; 34 invC[n]=qpow(fac[n],mod-2); 35 for(int i=n-1;i>=0;--i) 36 invC[i]=(ll)invC[i+1]*(ll)(i+1)%mod; 37 for(int i=1;i<=n;++i) 38 inv[i]=qpow(i,mod-2); 39 C[0][0]=1; 40 for(int i=1;i<=n;++i) 41 { 42 C[i][0]=1; 43 for(int j=1;j<=i;++j) 44 { 45 C[i][j]=C[i-1][j]; 46 add(C[i][j],C[i-1][j-1]); 47 } 48 } 49 } 50 inline int read() 51 { 52 char ch=getchar(); 53 while(ch<'0'||'9'<ch) 54 ch=getchar(); 55 int sum=ch-'0'; 56 ch=getchar(); 57 while('0'<=ch&&ch<='9') 58 { 59 sum=sum*10+ch-'0'; 60 ch=getchar(); 61 } 62 return sum; 63 } 64 int main() 65 { 66 freopen("game.in","r",stdin); 67 freopen("game.out","w",stdout); 68 ios::sync_with_stdio(false); 69 n=read(); 70 init(); 71 for(int i=1;i<=n;++i) 72 { 73 a[i]=read(); 74 if(a[i]==0) 75 { 76 cout<<0<<endl; 77 return 0; 78 } 79 ++larger[a[i]]; 80 } 81 for(int i=n-1;i>=1;--i) 82 larger[i]+=larger[i+1]; 83 for(int i=1;i<=n;++i) 84 for(int j=1;j<=i+1;++j) 85 { 86 f[i][j]=new int[i/j+4]; 87 for(int k=0;k<=i/j+3;++k) 88 f[i][j][k]=0; 89 } 90 for(int j=1;j<=n+1;++j) 91 { 92 f[0][j]=new int[3]; 93 for(int k=0;k<=2;++k) 94 f[0][j][k]=0; 95 } 96 f[0][n+1][0]=1; 97 for(int i=1;i<=n+1;++i) 98 sum[0][i]=1; 99 for(int i=1;i<=n;++i) 100 { 101 for(int j=1;j<=i;++j) 102 { 103 if(sum[i-j][j+1]) 104 f[i][j][1]=(ll)sum[i-j][j+1]*(ll)C[larger[j]-i+j][j]%mod; 105 for(int k=2;i-j*k>=0;++k) 106 { 107 if(f[i-j][j][k-1]) 108 f[i][j][k]=(ll)f[i-j][j][k-1]*(ll)inv[k]%mod*(ll)C[larger[j]-i+j][j]%mod; 109 } 110 } 111 for(int j=i+1;j>=1;--j) 112 { 113 sum[i][j]=sum[i][j+1]; 114 for(int k=1;i-j*k>=0;++k) 115 add(sum[i][j],f[i][j][k]); 116 } 117 } 118 ans=0; 119 for(int i=1;i<=n;++i) 120 for(int j=1;n-i*j>=0;++j) 121 add(ans,f[n][i][j]); 122 cout<<ans<<endl; 123 return 0; 124 }