D. Colored Balls

D. Colored Balls

There are balls of n different colors; the number of balls of the i-th color is ai.

The balls can be combined into groups. Each group should contain at most 2 balls, and no more than 1 ball of each color.

Consider all 2n sets of colors. For a set of colors, let's denote its value as the minimum number of groups the balls of those colors can be distributed into. For example, if there are three colors with 3, 1 and 7 balls respectively, they can be combined into 7 groups (and not less than 7), so the value of that set of colors is 7.

Your task is to calculate the sum of values over all 2n possible sets of colors. Since the answer may be too large, print it modulo 998244353.

Input

The first line contains a single integer n (1n5000) — the number of colors.

The second line contains n integers a1,a2,,an (1ai5000) — the number of balls of the i-th color.

Additional constraint on input: the total number of balls doesn't exceed 5000.

Output

Print a single integer — the sum of values of all 2n sets of colors, taken modulo 998244353.

Examples

input

3
1 1 2

output

11

input

1
5

output

5

input

4
1 3 3 7

output

76

Note

Consider the first example. There are 8 sets of colors:

  • for the empty set, its value is 0;
  • for the set {1}, its value is 1;
  • for the set {2}, its value is 1;
  • for the set {3}, its value is 2;
  • for the set {1,2}, its value is 1;
  • for the set {1,3}, its value is 2;
  • for the set {2,3}, its value is 2;
  • for the set {1,2,3}, its value is 2.

So, the sum of values over all 2n sets of colors is 11.

 

解题思路

  题目给出的组合规则其实就是摩尔投票。即确定颜色的方案后,假设球的总数为 m,所有颜色中数量最多的球有 x 个,则分组数量的最小值分两种情况:

  • 如果 xmx,则至少分成 m2 组。
  • 如果 x>mx,则至少分成 x 组。

更新:该定理的扩展可参考 A. Cards Partition

  所以我们可以对数组 a 升序排序,固定数量最多的球 ai,用 f(i1,j) 来表示所有不超过 ai 的球(即 a1ai1)组成总数为 j 的方案数量。那么以 ai 作为数量最多的球的所有方案中,贡献的答案是(其中 m=ai):

j=0ai1aif(i1,j)+j=aimj+ai2f(i1,j)

  其中 f(i,j) 根据是否选择 ai 进行状态划分(01 背包),转移方程为 f(i,j)=f(i1,j)+f(i1,jai)

  AC 代码如下,时间复杂度为 O(nai)

#include <bits/stdc++.h>
using namespace std;

typedef long long LL;

const int N = 5005, mod = 998244353;

int a[N];
int f[N][N];

int main() {
    int n, m = 0;
    scanf("%d", &n);
    for (int i = 1; i <= n; i++) {
        scanf("%d", a + i);
        m += a[i];
    }
    sort(a + 1, a + n + 1);
    int ret = 0;
    f[0][0] = 1;
    for (int i = 1; i <= n; i++) {
        for (int j = 0; j <= m; j++) {
            if (j >= a[i]) ret = (ret + (j + a[i] + 1ll) / 2 * f[i - 1][j]) % mod;
            else ret = (ret + 1ll * a[i] * f[i - 1][j]) % mod;
            f[i][j] = f[i - 1][j];
            if (j >= a[i]) f[i][j] = (f[i][j] + f[i - 1][j - a[i]]) % mod;
        }
    }
    printf("%d", ret);
    
    return 0;
}

 

参考资料

  Educational Codeforces Round 164 (Rated for Div. 2) A~E - 知乎:https://zhuanlan.zhihu.com/p/692227075

posted @   onlyblues  阅读(212)  评论(4编辑  收藏  举报
相关博文:
阅读排行:
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探
· 为什么 退出登录 或 修改密码 无法使 token 失效
历史上的今天:
2022-04-13 查询字符串
2021-04-13 Saving James Bond - Hard Version
Web Analytics
点击右上角即可分享
微信分享提示