小W与大数
小W与大数
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

相关文章:

  • 2021-12-15
  • 2022-01-20
  • 2022-12-23
  • 2022-01-12
  • 2022-12-23
  • 2021-07-07
  • 2022-02-15
  • 2021-08-16
猜你喜欢
  • 2021-04-14
  • 2021-12-28
  • 2021-06-24
  • 2021-10-17
  • 2021-12-18
  • 2021-07-06
  • 2021-10-08
相关资源
相似解决方案