AtcoderABC262 D

这篇博客介绍了Atcoder ABC262的竞赛题目,该题目涉及计算从给定正整数序列中选择一个或多个数,使得它们的平均数为整数的所有可能组合数量。博主提供了算法思路,使用动态规划的方法,时间复杂度为O(n^4),并在限制时间内得出正确答案。
摘要由CSDN通过智能技术生成

AtcoderABC262

题目描述

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 2N1 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 1N100
  • 1 ≤ a i ≤ 1 0 9 1\leq a_i\leq 10^9 1ai109
  • 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 2n1种方式选择一个或多个数。其中有多少种方式使其平均数为整数。答案模 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=fi1,jai,k1+fi1,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;
}
  • 4
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值