Codeforces Round 916 (Div. 3) D 题 Three Activities

题目描述

Winter holidays are coming up. They are going to last for nn days.

During the holidays, Monocarp wants to try all of these activities exactly once with his friends:

  • go skiing;
  • watch a movie in a cinema;
  • play board games.

Monocarp knows that, on the i -th day, exactly ai​ friends will join him for skiing, bi​ friends will join him for a movie and cici​ friends will join him for board games.

Monocarp also knows that he can't try more than one activity in a single day.

Thus, he asks you to help him choose three distinct days x,y,z in such a way that the total number of friends to join him for the activities ( ax+by+cz​ ) is maximized.

输入格式

The first line contains a single integer t ( 1≤t≤104 ) — the number of testcases.

The first line of each testcase contains a single integer n ( 3≤n≤105 ) — the duration of the winter holidays in days.

The second line contains nn integers a1,a2,…,an​ ( 1≤ai≤108 ) — the number of friends that will join Monocarp for skiing on the i -th day.

The third line contains nn integers b1,b2,…,bn​ ( 1≤bi≤108 ) — the number of friends that will join Monocarp for a movie on the i -th day.

The fourth line contains nn integers c1,c2,…,cn ( 1≤ci≤108 ) — the number of friends that will join Monocarp for board games on the i -th day.

The sum of n over all testcases doesn't exceed 105 .

输出格式

For each testcase, print a single integer — the maximum total number of friends that can join Monocarp for the activities on three distinct days.

题意翻译

给定三个数组 a,b,c,找三个互不相同的整数 i,j,k,使得 ai+bj+ck 的值最大。

输入输出样例

输入 #1复制

4
3
1 10 1
10 1 1
1 1 10
4
30 20 10 1
30 5 15 20
30 25 10 10
10
5 19 12 3 18 18 6 17 10 13
15 17 19 11 16 3 11 17 17 17
1 17 18 10 15 8 17 3 13 12
10
17 5 4 18 12 4 11 2 16 16
8 4 14 19 3 12 6 7 5 16
3 4 8 11 10 8 10 2 20 3

输出 #1复制

30
75
55
56

说明/提示

In the first testcase, Monocarp can choose day 2 for skiing, day 1 for a movie and day 3 for board games. This way, a2=10 friends will join him for skiing, b1=10 friends will join him for a movie and c3=10 friends will join him for board games. The total number of friends is 30.

In the second testcase, Monocarp can choose day 1 for skiing, day 4 for a movie and day 2 for board games. 30+20+25=75 friends in total. Note that Monocarp can't choose day 1 for all activities, because he can't try more than one activity in a single day.

In the third testcase, Monocarp can choose day 2 for skiing, day 3 for a movie and day 7 for board games. 19+19+17=55 friends in total.

In the fourth testcase, Monocarp can choose day 1 for skiing, day 4 for a movie and day 9 for board games. 17+19+20=56 friends in total.


思路:

只要是不同的三天就可以,这样的话,我们只需要将a中人数由大到小的下标取前3,b中人数由大到小取前3,c中从大到小取前3,然后枚举,一共是 3^{3} 种情况其中再去掉一些重复的,为什么要取前3呢,假设说a这项活动把第一天占用了,对于b这项活动,第一天不能用了,还有第二大和第三大,对于c这项活动如果它的前两大的下标都和a,b重复了,他还可以取第三大,因此几乎总是可以取每个数组中的最大值。而当你不能取最大值时,就不需要考虑很多较小的数字。特别是,只需考虑每个数组中最大的三个数即可。


代码实现:
 

#include<bits/stdc++.h>

using namespace std;

void solve()
{
    int n;
    cin>>n;

    vector<int> a(n),b(n),c(n);

    for(int i=0;i<n;i++)
    {
        cin>>a[i];
    }

    for(int i=0;i<n;i++)
    {
        cin>>b[i];
    }

    for(int i=0;i<n;i++)
    {
        cin>>c[i];
    }

    vector<int> pa(n),pb(n),pc(n);

    iota(pa.begin(),pa.end(),0);
    iota(pb.begin(),pb.end(),0);
    iota(pc.begin(),pc.end(),0);

    sort(pa.begin(),pa.end(),
         [&](int i,int j)
         {
             return a[i]>a[j];
         });
    sort(pb.begin(),pb.end(),
         [&](int i,int j)
         {
             return b[i]>b[j];
         });
    sort(pc.begin(),pc.end(),
         [&](int i,int j)
         {
             return c[i]>c[j];
         });

    int ans=0;

    for(int i=0;i<3;i++)
    {
        for(int j=0;j<3;j++)
        {
            for(int k=0;k<3;k++)
            {
                int x=pa[i],y=pb[j],z=pc[k];
                if(x!=y && x!=z && y!=z)
                {
                    ans=max(ans,a[x]+b[y]+c[z]);
                }
            }
        }
    }

    cout<<ans<<endl;
}

int main()
{
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    int t;
    cin>>t;

    while(t--)
    {
        solve();
    }
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值