G 篮球校赛(CCPC-Wannafly & Comet OJ 夏季欢乐赛(2019)) 两种方法(5重循环和DFS)

25 篇文章 0 订阅
21 篇文章 0 订阅

题目描述

 

JWJU注重培养学生的“唱,跳,rap,篮球”能力。于是每年JWJU都会举办篮球校赛,来给同学们一个切磋篮球技术的平台。校赛冠军的奖励是看wls女装一次,为了这个目标,大家都努力训练,希望自己能看到wls女装。

教练my手下有 n 名队员,现在他要挑选 5 人组成一个篮球队来参赛。众所周知,一个篮球队伍有五个不同的位置(控球后卫,得分后卫,小前锋,大前锋,中锋),现在教练mymy给出每名队员在每个位置的能力。

注:如果一个队员作为控球后卫出战,则他只能发挥他的控球后卫的能力值。(其他位置类似)

教练mymy想让你帮忙选择出 55名队员,分别放置在队伍中的不同位置。求他们组成的队伍的最大能力值之和。

输入描述

输出第一行包含一个正整数 n (5≤n≤105)。

接下来包含 n 行,每行包含 5 个正整数,描述每个队员在每个位置的能力值。每项能力值的取值范围都在 [1,1e9]。

输出描述

 

输出一行一个正整数代表组成的队伍的最大能力值之和。

样例输入
5
10 11 12 15 10
10 15 12 11 10
15 10 15 15 15
19 20 114000 10 300
14 10 155 200 469
样例输出 
114514

提示

第一个人放在位置4,发挥15的能力值

第二个人放在位置2,发挥15的能力值

第三个人放在位置1,发挥15的能力值

第四个人放在位置3,发挥114000的能力值

第五个人放在位置5,发挥469的能力值

团队总能力值:15+15+15+114000+469=11451415+15+15+114000+469=11451

思路:每一个位置找出前5个,最多遍历25个。

方法1:(5重循环)

#include <algorithm>
#include <iostream>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <cstdlib>
using namespace std;
typedef long long ll;
struct A
{
    ll w[6];
    int flag=0;
}a[100010],b[100];
int cmp1(A x,A y)
{
    return x.w[1]>y.w[1];
}
int cmp2(A x,A y)
{
    return x.w[2]>y.w[2];
}
int cmp3(A x,A y)
{
    return x.w[3]>y.w[3];
}
int cmp4(A x,A y)
{
    return x.w[4]>y.w[4];
}
int cmp5(A x,A y)
{
    return x.w[5]>y.w[5];
}
int main()
{
    ll n,ans=0,e=0,i,j,k,ii,jj;
    cin>>n;
    for(i=0;i<n;i++)
    {
        for(j=1;j<=5;j++)
        {
            cin>>a[i].w[j];
        }
    }
    sort(a,a+n,cmp1);
    for(i=0;i<5;i++)
    {
        if(a[i].flag==0)
        {
            b[e++]=a[i];
            a[i].flag=1;
        }
    }
    sort(a,a+n,cmp2);
    for(i=0;i<5;i++)
    {
        if(a[i].flag==0)
        {
            b[e++]=a[i];
            a[i].flag=1;
        }
    }
    sort(a,a+n,cmp3);
    for(i=0;i<5;i++)
    {
        if(a[i].flag==0)
        {
            b[e++]=a[i];
            a[i].flag=1;
        }
    }
    sort(a,a+n,cmp4);
    for(i=0;i<5;i++)
    {
        if(a[i].flag==0)
        {
            b[e++]=a[i];
            a[i].flag=1;
        }
    }
    sort(a,a+n,cmp5);
    for(i=0;i<5;i++)
    {
        if(a[i].flag==0)
        {
            b[e++]=a[i];
            a[i].flag=1;
        }
    }
    ll sum=0;
    for(i=0;i<e;i++)
     for(j=0;j<e;j++)
      for(k=0;k<e;k++)
       for(ii=0;ii<e;ii++)
        for(jj=0;jj<e;jj++)
         if(i!=j&&i!=k&&i!=ii&&i!=jj&&j!=k&&j!=ii&&j!=jj&&k!=ii&&k!=jj&&ii!=jj)
         {
             sum=b[i].w[1]+b[j].w[2]+b[k].w[3]+b[ii].w[4]+b[jj].w[5];
             ans=max(ans,sum);
         }
    cout<<ans<<endl;
    return 0;
}

方法2:(DFS  )

#include <algorithm>
#include <iostream>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <cstdlib>
using namespace std;
typedef long long ll;
struct A
{
    ll w[6];
    int flag=0;
}a[100010],b[100];
ll ans=0,e=0;
int cmp1(A x,A y)
{
    return x.w[1]>y.w[1];
}
int cmp2(A x,A y)
{
    return x.w[2]>y.w[2];
}
int cmp3(A x,A y)
{
    return x.w[3]>y.w[3];
}
int cmp4(A x,A y)
{
    return x.w[4]>y.w[4];
}
int cmp5(A x,A y)
{
    return x.w[5]>y.w[5];
}
int flag[10]={0};
void DFS(ll num,ll sum)//num是第几个人,sum是当前总和
{
    ans=max(ans,sum);
    if(num==e)//搜完了
       return ;
    int i;
    for(i=1;i<=5;i++)
    {
        if(flag[i]==0)
        {
            flag[i]=1;
            DFS(num+1,sum+b[num].w[i]);//往下搜索
            flag[i]=0;
        }
    }
    if(i>5)//还有剩余的人时,只往下搜sum不变
        DFS(num+1,sum);
}
int main()
{
    ll n,i,j,k,ii,jj;
    cin>>n;
    for(i=0;i<n;i++)
     for(j=1;j<=5;j++)
        cin>>a[i].w[j];
    sort(a,a+n,cmp1);
    for(i=0;i<5;i++)
    {
        if(a[i].flag==0)
        {
            b[e++]=a[i];
            a[i].flag=1;
        }
    }
    sort(a,a+n,cmp2);
    for(i=0;i<5;i++)
    {
        if(a[i].flag==0)
        {
            b[e++]=a[i];
            a[i].flag=1;
        }
    }
    sort(a,a+n,cmp3);
    for(i=0;i<5;i++)
    {
        if(a[i].flag==0)
        {
            b[e++]=a[i];
            a[i].flag=1;
        }
    }
    sort(a,a+n,cmp4);
    for(i=0;i<5;i++)
    {
        if(a[i].flag==0)
        {
            b[e++]=a[i];
            a[i].flag=1;
        }
    }
    sort(a,a+n,cmp5);
    for(i=0;i<5;i++)
        if(a[i].flag==0)
        {
            b[e++]=a[i];
            a[i].flag=1;
        }
    DFS(0,0);
    cout<<ans<<endl;
    return 0;
}

 

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值