题目描述
You are given a sequence of positive integers
A
=
(
a
1
,
a
2
,
…
,
a
N
)
A=(a_1,a_2,\dots,a_N)
A=(a1,a2,…,aN) of length
N
N
N.
There are
2
N
−
1
2^N-1
2N−1 ways to choose one or more terms of
A
A
A. How many of them have an integer-valued average?Find the count modulo
998244353
998244353
998244353.
Sample Input 1
3
2 6 2
Sample Output 1
6
Sample Input 2
5
5 5 5 5 5
Sample Output 2
31
- 1 ≤ N ≤ 100 1\leq N \leq 100 1≤N≤100
- 1 ≤ a i ≤ 1 0 9 1\leq a_i\leq 10^9 1≤ai≤109
- All values in input are integers.
题目大意
给一个长度为 n n n的正整数序列 A = ( a 1 , a 2 , … , a n ) A=(a_1,a_2,\dots,a_n) A=(a1,a2,…,an),有 2 n − 1 2^n-1 2n−1种方式选择一个或多个数。其中有多少种方式使其平均数为整数。答案模 998244353 998244353 998244353。
题解
我们可以先枚举选择的个数,设选择 t t t个,则选择的 t t t个数的和模 t t t必须为0。
设 f i , j , k f_{i,j,k} fi,j,k表示当前枚举到第 i i i个数,选择的数的和模 t t t的值为 j j j,共选择了 k k k个数时能满足题意的选择方式的数量。转移式为
f i , j , k = f i − 1 , j − a i , k − 1 + f i − 1 , j , k f_{i,j,k}=f_{i-1,j-a_i,k-1}+f_{i-1,j,k} fi,j,k=fi−1,j−ai,k−1+fi−1,j,k
相当于做 n n n次背包。
总时间复杂度 O ( n 4 ) O(n^4) O(n4),但是跑不满,而且时限2500ms,所以可以过。
code
#include<bits/stdc++.h>
using namespace std;
int n,a[105];
long long ans=0,f[105][105][105];
long long mod=998244353;
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%d",&a[i]);
}
for(int o=1;o<=n;o++){
memset(f,0,sizeof(f));
f[0][0][0]=1;
for(int i=1;i<=n;i++){
for(int j=0;j<o;j++){
int v=(j+a[i])%o;
for(int k=1;k<=o;k++){
f[i][v][k]=(f[i][v][k]+f[i-1][j][k-1])%mod;
f[i][j][k]=(f[i][j][k]+f[i-1][j][k])%mod;
}
f[i][j][0]=(f[i][j][0]+f[i-1][j][0])%mod;
}
}
ans=(ans+f[n][0][o])%mod;
}
printf("%lld",ans);
return 0;
}