11的倍数,满足奇数位减偶数位,之差是11的倍数,当n<=10的时候可以全排列一下数组的下标然后再时间复杂度比较差
#include <bits/stdc++.h>
using namespace std;
const int maxn=2333;
const int mod=998244353;
long long n,a[maxn],b[maxn],s[maxn],l[maxn],c[maxn][20],n1,n2,dp[maxn][maxn][11],f[maxn][maxn][11],p[maxn],inv[maxn];
void add(long long &x,long long y)
{
x+=y;
if(x>=mod) x-=mod;
}
int C(int n,int m)
{
return(long long)p[n]*inv[m]%mod*inv[n-m]%mod;
}
int Get_C(int m,int n)
{
if(m==0) return n?0:1;
return(long long)p[n]*C(n+m-1,n)%mod;
}
void init()
{
p[0]=1;
for(int i=1;i<=n+5;i++)
{
p[i]=(long long)p[i-1]*i%mod;
}
inv[0]=inv[1]=1;
for(int i=2;i<=n+5;i++)
{
inv[i]=(long long)(mod-mod/i)*inv[mod%i]%mod;
}
for(int i=2;i<=n+5;i++)
{
inv[i]=(long long)inv[i]*inv[i-1]%mod;
}
}
void Subtask1()
{
int ans=0;
for(int i=1;i<=n;i++)
{
int x=a[i];
while(x)
{
c[i][++l[i]]=x%10;
x/=10;
}
for(int j=1;j<=(l[i]/2);j++)
{
swap(c[i][j],c[i][l[i]-j+1]);
}
}
for(int i=1;i<=n;i++)
{
b[i]=i;
}
while(next_permutation(b+1,b+1+n))
{
long long val=0,now=0,v1=0,v2=0;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=l[b[i]];j++)
{
now++;
if(now%2) v1+=c[b[i]][j];
else v2+=c[b[i]][j];
}
}
val=abs(v1-v2);
if((val%11)==0) ans++;
}
cout<<ans<<endl;
}
void Subtask2()
{
for(int i=1;i<=n;i++)
{
int len=0,now=a[i];
while(now)
{
now/=10;
len++;
}
if(len&1) b[++n1]=a[i]%11;
else s[++n2]=a[i]%11;
}
for(int i=0;i<=n;i++)
{
for(int j=0;j<11;j++)
{
dp[0][i][j]=f[0][i][j]=0;
}
}
dp[0][0][0]=1;
for(int i=1;i<=n1;i++)
{
for(int j=0;j<=i;j++)
{
for(int k=0;k<11;k++)
{
dp[i][j][k]=0;
add(dp[i][j][k],dp[i-1][j][(k-b[i]+11)%11]);
if(j) add(dp[i][j][k],dp[i-1][j-1][(k+b[i])%11]);
}
}
}
f[0][0][0]=1;
for(int i=1;i<=n2;i++)
{
for(int j=0;j<=i;j++)
{
for(int k=0;k<11;k++)
{
f[i][j][k]=0;
add(f[i][j][k],f[i-1][j][(k-s[i]+11)%11]);
if(j) add(f[i][j][k],f[i-1][j-1][(k+s[i])%11]);
}
}
}
long long ans=0;
for(int i=0;i<=n2;i++)
{
for(int k=0;k<11;k++)
{
long long val=(long long)dp[n1][n1/2][k]*p[n1/2]%mod*p[n1-n1/2]%mod*f[n2][i][(11-k)%11]%mod*Get_C(n1+1-(n1+1)/2,n2-i)%mod*Get_C((n1+1)/2,i)%mod;
add(ans,val);
}
}
cout<<ans<<endl;
}
int main()
{
cin>>n;
n1=n2=0;
init();
for(int i=1;i<=n;i++) cin>>a[i];
if(n<=10)
{
Subtask2();
return 0;
}
Subtask2();
return 0;
}
来源:zr