HDU 5744 Keep On Movin (贪心)

本文探讨了使用多种字符构建多个回文串的问题,旨在最大化最短回文串的长度。通过分析字符数量,确定中心点及分配剩余字符,提出了有效的解决方案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Keep On Movin

题目链接:

http://acm.hdu.edu.cn/showproblem.php?pid=5744

Description

Professor Zhang has kinds of characters and the quantity of the i-th character is ai. Professor Zhang wants to use all the characters build several palindromic strings. He also wants to maximize the length of the shortest palindromic string.

For example, there are 4 kinds of characters denoted as 'a', 'b', 'c', 'd' and the quantity of each character is {2,3,2,2} . Professor Zhang can build {"acdbbbdca"}, {"abbba", "cddc"}, {"aca", "bbb", "dcd"}, or {"acdbdca", "bb"}. The first is the optimal solution where the length of the shortest palindromic string is 9.

Note that a string is called palindromic if it can be read the same way in either direction.

Input

There are multiple test cases. The first line of input contains an integer T, indicating the number of test cases. For each test case:

The first line contains an integer n (1≤n≤105) -- the number of kinds of characters. The second line contains n integers a1,a2,...,an (0≤ai≤104).

Output

For each test case, output an integer denoting the answer.

Sample Input

4
4
1 1 2 4
3
2 2 2
5
1 1 1 1 1
5
1 1 2 2 3

Sample Output

3
6
1
3

Source

2016 Multi-University Training Contest 2


题意:


给出n种字符的各自的数量,用它们构成多个回文串,求最短回文串的最大长度.


题解:


首先,如果某个字符有奇数个,那么单出来的那个肯定要放在某个回文串的中心位置.
那么可以先找出最少有多少个这样的中心点.
对于剩下的字符(肯定是偶数个), 要把它们平均分配到这些中心点两边.
这里要注意:每个中心点被额外分配的字符个数一定是偶数.


代码:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <queue>
#include <map>
#include <set>
#include <vector>
#define LL long long
#define double LL
#define eps 1e-8
#define maxn 101000
#define mod 1000000007
#define inf 0x3f3f3f3f
#define IN freopen("in.txt","r",stdin);
using namespace std;

int n;
int num[maxn];

int main(void)
{
    //IN;

    int t; cin >> t;
    while(t--)
    {
        cin >> n;
        int center = 0;
        int extra = 0;
        for(int i=1; i<=n; i++) {
            scanf("%d", &num[i]);
            extra += num[i];
            if(num[i]&1) center++,extra--;
        }

        int ans;
        if (!center || (extra%center==0 && (extra/center)%2==0)) {
            if(!center) ans = extra;
            else ans = extra/center + 1;
        }else {
            int tmp = extra/center;
            if(tmp&1) ans = tmp-1;
            else ans = tmp;
            ans += 1;
        }

        printf("%d\n", ans);
    }

    return 0;
}

转载于:https://www.cnblogs.com/Sunshine-tcf/p/5709504.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值