UESTC 1279 班委选举(dfs)

题目链接:

http://acm.uestc.edu.cn/#/problem/show/1279

Description

高考的脚步越来越近了……时间如山涧小溪一般悄无声息地流走,一去不复还……曾几何时嬉笑的最后一排,如今也已经被大大小小的书本填完,我们从未有过为一件事如此认真过,但我们坚信我们的付出是值得的。

班长曲琪打破了班级久久的寂静。她咳了咳嗽,缓缓地走上讲台,学习委员乔伊也起身走向讲台。

“我们将进行我们最后一次班委选举,对吧副班长”。曲琪虽然尽力使用高兴的语气,但是难掩心中的将要与他离别和与他不确定的未来的惆怅。 title

“我是学委”。乔伊再一次提醒曲琪,然而曲琪总是喜欢叫他副班长。乔伊紧接着说:“作为我们最后一次的班委选举,我和曲琪想了很多选择方式,我们接下来要展示的是我们的选拔标准”。

曲琪将手里的方案书打开,无意间一个小小盒子从手里掉了出来,曲琪马上把盒子捡了起来-那可是给他的生日礼物-一盒小小的曲奇饼。

“每……每位学生只能担任一个职务,不可以……不可以担任多个职务”,曲琪的心里小鹿乱撞生怕被他看到了礼物,涨红着脸读着方案书。

“我们将选出6位课代表,根据梅老师的带班经验一个班级的学习能力等于各科课代表的对应学科的学科能力总和”。 title

梅老师说:“同学们,我通过各科老师给你们的各科学习能力评了分用一个0-100以内的整数表示,作为你们的班主任我想通过这次的班委选举,全力提高我们的班级学习能力。” title

罗小涵:“求最大的班级学习能力这种事情还是很容易直接算出的吧,对吧”。

你:“怎么可能啊,N个人快N^6种安排方式,你看木馨算了好久了,都没有算出来,呀,她怎么睡着了”。

罗小涵:“……迟钝”。

Input

输入一个整数N(6<=N<=1000)表示你班级的人数。

接下去N行,第i行有6个整数pi(0<=pi<=100)表示第i个人的语文,数学,英语,化学,物理,生物能力。

Output

输出一个数表示这个班级的最大的班级学习能力(各科课代表的对应学科的学科能力总和)。

Sample Input

6
41 85 72 38 80 69
65 68 96 22 49 67
51 61 63 87 66 24
80 83 71 60 64 52
90 60 49 31 23 99
94 11 25 24 51 15

Sample Output

539

Hint


思路:

(冷静分析,暴力枚举,A(N,6),超时,不行),再次冷静分析,其实有用的最多36个人,我们保存下每个课程最高能力的6个人,然后搜索,复杂度6^6

码力弱,写得有点复杂,23333.....

附上代码:

#include<cstdio>
#include<cmath>
#include<cstring>
#include<string>
#include<cstdlib>
#include<algorithm>
#include<iostream>
#include<queue>
#include<stack>

using namespace std;

#define FOU(i,x,y) for(int i=x;i<=y;i++)
#define FOD(i,x,y) for(int i=x;i>=y;i--)
#define MEM(a,val) memset(a,val,sizeof(a))
#define PI acos(-1.0)

const double EXP = 1e-9;
typedef long long ll;
typedef unsigned long long ull;
const int INF = 0x3f3f3f3f;
const ll MINF = 0x3f3f3f3f3f3f3f3f;
const int mod = 1e9+7;
const int N = 1e6+5;

struct node
{
    int a[7];
    int id;
}people[1005];

struct node1
{
    int b[7];
    int num[7];
}per[10];  //用于保存6个向量最大的前6个值,pre[i]代表第i门课

int ans,n;
int vis[1005];

bool cmp1(node x,node y)
{
    return x.a[1]>y.a[1];
}

bool cmp2(node x,node y)
{
    return x.a[2]>y.a[2];
}

bool cmp3(node x,node y)
{
    return x.a[3]>y.a[3];
}

bool cmp4(node x,node y)
{
    return x.a[4]>y.a[4];
}

bool cmp5(node x,node y)
{
    return x.a[5]>y.a[5];
}

bool cmp6(node x,node y)
{
    return x.a[6]>y.a[6];
}

void dfs(int sum,int step)  //sum代表总和,step代表第几科
{
    if(step==7)
    {
        ans=max(ans,sum);
        //printf("ans=%d\n",ans);
        return ;
    }
    for(int i=1;i<=6;i++)   //从每一科最大的6个人中选
    {
        if(vis[per[step].num[i]]==0)
        {
            vis[per[step].num[i]]=1;
            dfs(sum+per[step].b[i],step+1);
            vis[per[step].num[i]]=0;
        }
    }
}

int main()
{
    //freopen("in.txt","r",stdin);
    //freopen("out.txt","w",stdout);
    std::ios::sync_with_stdio(false);
    while(~scanf("%d",&n))
    {
        for(int i=1;i<=n;i++)
        {
            for(int j=1;j<=6;j++)
            {
                scanf("%d",&people[i].a[j]);
                people[i].id=i;
            }
        }
        sort(people+1,people+1+n,cmp1);
        for(int i=1;i<=6;i++)
        {
            per[1].b[i]=people[i].a[1];
            per[1].num[i]=people[i].id;
            //printf("1:%d %d\n",per[1].b[i],per[1].num[i]);
        }
        sort(people+1,people+1+n,cmp2);
        for(int i=1;i<=6;i++)
        {
            per[2].b[i]=people[i].a[2];
            per[2].num[i]=people[i].id;
        }
        sort(people+1,people+1+n,cmp3);
        for(int i=1;i<=6;i++)
        {
            per[3].b[i]=people[i].a[3];
            per[3].num[i]=people[i].id;
        }
        sort(people+1,people+1+n,cmp4);
        for(int i=1;i<=6;i++)
        {
            per[4].b[i]=people[i].a[4];
            per[4].num[i]=people[i].id;
        }
        sort(people+1,people+1+n,cmp5);
        for(int i=1;i<=6;i++)
        {
            per[5].b[i]=people[i].a[5];
            per[5].num[i]=people[i].id;
        }
        sort(people+1,people+1+n,cmp6);
        for(int i=1;i<=6;i++)
        {
            per[6].b[i]=people[i].a[6];
            per[6].num[i]=people[i].id;
        }
        ans=0;
        MEM(vis,0);
        dfs(0,1);
        printf("%d\n",ans);
    }
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值