B. Olya and Game with Arrays

目录

题目 

题目分析

解答

代码

代码详解与难点分析(可无)

分析

算法的性能分析


题目 

time limit per test

1 second

memory limit per test

256 megabytes

input

standard input

output

standard output

Artem suggested a game to the girl Olya. There is a list of nn arrays, where the ii-th array contains mi≥2mi≥2 positive integers ai,1,ai,2,…,ai,miai,1,ai,2,…,ai,mi.

Olya can move at most one (possibly 00) integer from each array to another array. Note that integers can be moved from one array only once, but integers can be added to one array multiple times, and all the movements are done at the same time.

The beauty of the list of arrays is defined as the sum ∑ni=1minmij=1ai,j∑i=1nminj=1miai,j. In other words, for each array, we find the minimum value in it and then sum up these values.

The goal of the game is to maximize the beauty of the list of arrays. Help Olya win this challenging game!

Input

Each test consists of multiple test cases. The first line contains a single integer tt (1≤t≤250001≤t≤25000) — the number of test cases. The description of test cases follows.

The first line of each test case contains a single integer nn (1≤n≤250001≤n≤25000) — the number of arrays in the list.

This is followed by descriptions of the arrays. Each array description consists of two lines.

The first line contains a single integer mimi (2≤mi≤500002≤mi≤50000) — the number of elements in the ii-th array.

The next line contains mimi integers ai,1,ai,2,…,ai,miai,1,ai,2,…,ai,mi (1≤ai,j≤1091≤ai,j≤109) — the elements of the ii-th array.

It is guaranteed that the sum of mimi over all test cases does not exceed 5000050000.

Output

For each test case, output a single line containing a single integer — the maximum beauty of the list of arrays that Olya can achieve.

每个test1秒的时间限制

每个测试的内存限制为256兆字节

inputstandard输入

outputstandard输出

阿尔乔姆向女孩奥利娅建议玩一个游戏。存在一个包含n个数组的列表,其中第i个数组包含mi≥2个正整数ai,1,ai,2,…,ai,mi。

Olya最多可以将一个整数(可能为0)从一个数组移动到另一个数组。请注意,整数只能从一个数组中移动一次,但整数可以多次添加到一个数组中,并且所有移动都是同时完成的。

数组列表的美妙之处在于求和∑ni=1minmij=1ai,j。换句话说,对于每个数组,我们找到其中的最小值,然后将这些值相加。

游戏的目标是最大化数组列表的美感。帮助奥利亚赢得这个具有挑战性的游戏!

输入

每个测试由多个测试用例组成。第一行包含一个整数t(1≤t≤25000)——测试用例的数量。下面是测试用例的描述。

每个测试用例的第一行包含一个整数n(1≤n≤25000)——列表中的数组数。

后面是数组的描述。每个数组描述由两行组成。

第一行包含一个整数mi(2≤mi≤50000)——第i个数组中的元素数。

下一行包含mi个整数ai,1,ai,2,…,ai,mi(1≤ai,j≤109)-第i个数组的元素。

可以保证所有测试用例的mi之和不超过50000。

输出

对于每个测试用例,输出包含单个整数的单行—这是Olya可以实现的数组列表的最大美感。

输入范例

3
2
2
1 2
2
4 3
1
3
100 1 6
3
4
1001 7 1007 5
3
8 11 6
2
2 9

输出范例

5
1
19

示例解释:

In the first test case, we can move the integer 33 from the second array to the first array. Then the beauty is min(1,2,3)+min(4)=5min(1,2,3)+min(4)=5. It can be shown that this is the maximum possible beauty.

In the second test case, there is only one array, so regardless of the movements, the beauty will be min(100,1,6)=1min(100,1,6)=1.

在第一个测试用例中,我们可以将整数3从第二个数组移动到第一个数组。那么美就是min(1,2,3)+min(4)=5。可以证明,这是最大可能的美。

在第二个测试用例中,只有一个数组,因此无论移动如何,美感都将是min(100,1,6)=1。

 

题目分析

我一开始看错了题目,把题目理解成了,总共只移动一个数字,让他beauty最大化,最后代码写出来也挺不容易的,就先把这个整理了吧,抽空再去整理这道题的正解

解答

先建立两个表,一个是所有数列最小与第二小的差值表,一个是所有数列最小值表。

主要是比较每一个数列最小值与第二小的数值之间的差距,然后选出来差距最大(最大差距为m)的那个数列a的最小值p,看看是不是所有数列最小值中最小的那个,

如果不是,那么好,把这个差距最大的那个数列的最小值放到任意一个最小值比他大的数列b中,那个数列b的最小值不变,而且数列a的最小值还会比移动之前多了m,

如果是,那么好吧,只能让第一大差距m减去数列最小值序列中第二小x和最小的差值y,然后再与第二大的差距n比较,因为如果m-x+y<n的话说明就算把m对应队列中的最小值p放到n对应的c队列中他也是不如直接把n对应队列放到任意一个最小值比n对应队列大的数列中,如果m-x+y>n同样如此理解。

代码

#include "bits/stdc++.h"

using namespace std;

bool cmp(const int a, const int b) {
    return a > b;
}

int main() {
    int num, n, len, tmp;
    cin >> num;//有num组测试数据
    for (int i = 0; i < num; i++) {
        vector<int> dif;
        vector<pair<int, int> > Min;//first放置数列中最小值,second放置数列对应的下标
        map<int, int> difindex;//first放置数列下标,second放置对应的差值
        cin >> n;//有n个数列
        int sum = 0;
        for (int j = 0; j < n; j++) {
            cin >> len;//这个数列长度为len
            multiset<int> arr;
            for (int k = 0; k < len; k++) {
                cin >> tmp;
                arr.insert(tmp);
            }
            auto item = arr.begin();//找到这个数列最小值
            Min.emplace_back(*item, j);
            difindex[j] = *(++item) - *(--item);
            dif.emplace_back(*(++item) - *(--item));
        }
        sort(dif.begin(), dif.end(), cmp);//对差值表排序
        sort(Min.begin(), Min.end());//对最小值表排序
        if (n > 1)//如果有一个以上的数列
            if (difindex[Min.at(0).second] == *dif.begin()) {
                if (dif.at(0) + Min.at(0).first - Min.at(1).first > dif.at(1)) {
                    sum += dif.at(0) + Min.at(0).first - Min.at(1).first;
                } else {
                    sum += dif.at(1);
                }
                for (auto x: Min)
                    sum += x.first;
            } else {
                for (auto x: Min)
                    sum += x.first;
                sum += dif.at(0);
            }
        else
            for (auto x: Min)
                sum += x.first;

        cout << sum << endl;
    }
    return 0;
}

代码详解与难点分析(可无)

他要取每一个数列中的最小值,这说明大于这个数列最小值的数进入此数列没问题,但是小于的就有问题,就会对最终的beauty造成损失,所以我要判断

差距最大(最大差距为m)的那个数列a的最小值p,是不是所有数列最小值中最小的那个

分析

算法的性能分析

懒得分析

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值