传送门
f
k
,
j
,
l
f_{k,j,l}
fk,j,l中
k
k
k为已选数个数,
j
j
j为要求选数个数,也是模数(对于一个数只有其对选数个数的模数有效),
l
l
l是目前这些数模
j
j
j的余数,于是又状移方程
f
k
,
j
,
l
→
f
k
+
1
,
j
,
(
l
+
a
[
i
]
)
m
o
d
j
f_{k,j,l}\rightarrow f_{k+1,j,(l+a[i])mod\ j}
fk,j,l→fk+1,j,(l+a[i])mod j
初状态f[0][j][0]=1
a
n
s
=
∑
f
j
,
j
,
0
ans=\sum f_{j,j,0}
ans=∑fj,j,0
数据小,考虑DP
#include<bits/stdc++.h>
using namespace std;
#define in Read()
int in{
int i=0,f=1; char ch=0;
while(!isdigit(ch)&&ch!='-') ch=getchar();
if(ch=='-') f=-1, ch=getchar();
while(isdigit(ch)) i=(i<<1)+(i<<3)+ch-48, ch=getchar();
return i*f;
}
const int N=110;
const int MOD=998244353;
int n,a[N],ans,f[N][N][N];
int main(){
// freopen("1.in","r",stdin);
n=in;
for(int i=1;i<=n;++i) a[i]=in;
for(int j=1;j<=n;++j){
f[0][j][0]=1;
for(int i=1;i<=n;++i){
int m=a[i]%j;
for(int k=i-1;k>=0;--k)
for(int l=0;l<j;++l){
(f[k+1][j][(l+m)%j]+=f[k][j][l])%=MOD;
}
}
}
for(int i=1;i<=n;++i) (ans+=f[i][i][0])%=MOD;
printf("%d\n",ans);
return 0;
}