东华OJ-基础题-76-最大效益(C++)

  • 问题描述
    明明的爸爸开了一家小公司,公司里有5名职员。今天,公司接待了5位客户。明明的爸爸知道,和任何一位客户谈判并签下合同都要花一整天的时间,而他又希望在一天之内,和这5位客户都签好合同。因此,明明的爸爸要求公司里的5名职员分别与1位客户谈判。

明明的爸爸也知道,这5名职员和5位客户的性格各不相同。因此,不同的职员与不同的客户谈判,会给公司带来不同的经济效益。他现在要做出一个决策,让5名职员分别与哪位客户谈判,才能让公司今天的总经济效益最大。

明明的爸爸首先做了一张5行5列的效益表,如下所示:

1 1 1 1 1
1 1 1 1 1
1 1 1 1 1
1 1 1 1 1
1 1 1 1 1

在这张效益表中,每行代表一名公司职员,每列代表一个客户,每行中的5个数字就表示了当该行所代表的公司职员和每位客户谈判时所能产生的效益。明明的爸爸就要通过这张效益表来决定哪位职员与哪位顾客谈判,然后能够使公司的效益最大。就拿上面这张表来看,由于无论哪位职员与哪位客户谈判,所产生的效益都是1,因此最大的效益就是5。这是最简单的一种情况,但是当效益表里的数字变得复杂,就很难进行选择,到底哪种组合方式才是最优的。因此明明的爸爸求助于你,帮助他解决这个问题。

明明的爸爸的问题可以归结为:给你一张5行5列的效益表,表中的数字均为大于等于0的整数,要求在这张表中选出5个数字,使这5个数字的和最大。(注:这5个数字分别来自表中的不同行不同列,即同一行只能选择一个数字,同一列也只能选择一个数字。)

  • 输入说明
    你写的程序要求从标准输入设备中读入测试数据作为你所写程序的输入数据。标准输入设备中有多组测试数据。每组测试数据占5行;每行包含5个正整数;第i行的第j个正整数Aij代表第i名职员与第j位客户谈判能为公司带来的经济效益(0≤Aij≤100, 1≤i,j≤5)。每组测试数据与其后一组测试数据之间没有任何空行;第一组测试数据前面以及最后一组测试数据后面也都没有任何空行。

  • 输出说明
    对于每一组测试数据,你写的程序要求计算出一组相应的运算结果,并将每组运算结果作为你所写程序的输出数据依次写入到标准输出设备中。每组运算结果为一个整数s,即这一天中公司的最大可能总经济效益。例如:当测试数据中的所有Aij(1≤i,j≤5)均为1时,运算结果s应为5。输出时,每组运算结果s单独占一行,其行首和行尾都没有任何空格或其他任何字符;每组运算结果与其后一组运算结果之间没有任何空行或其他任何字符,第一组运算结果前面以及最后一组运算结果后面也都没有任何空行或其他任何字符。
    注:通常,显示屏为标准输出设备。

  • 输入范例

98 97 96 95 94
1 2 3 4 5
11 22 33 44 55
66 77 88 99 1
13 32 64 7 86
  • 输出范例
318

#include <bits/stdc++.h>
using namespace std;
//五重枚举循环,对访问的列做标记,暴力破解
int get_max(int nums[5][5]) {
    int cur,max_sum ;
    int flag[5] = {0};
    for(int i =0; i<5; ++i) {
        cur = 0;
        flag[i] = 1;
        cur += nums[0][i];
        for (int j = 0; j < 5; ++j) {
            if (flag[j] == 1) {
                continue;
            }
            flag[j] = 1;
            cur += nums[1][j];
            for (int k = 0; k < 5; k++) {
                if (flag[k] == 1) {
                    continue;
                }
                flag[k] = 1;
                cur += nums[2][k];
                for (int l = 0; l < 5; l++) {
                    if (flag[l] == 1) {
                        continue;
                    }
                    flag[l] = 1;
                    cur += nums[3][l];
                    for (int m = 0; m < 5; m++) {
                        if (flag[m] == 1) {
                            continue;
                        }
                        flag[m] = 1;
                        cur += nums[4][m];
                        if (cur > max_sum) {
                            max_sum = cur;
                        }
                        flag[m] = 0;
                        cur -= nums[4][m];
                    }
                    flag[l] = 0;
                    cur -= nums[3][l];
                }
                flag[k] = 0;
                cur -= nums[2][k];
            }
            flag[j] = 0;
            cur -= nums[1][j];
        }
        flag[i] = 0;
        cur -= nums[0][i];
    }

    return max_sum;
}


int main() {
    int first;
    while(cin>>first) {
        int arr[5][5];
        arr[0][0] = first;
        for(int i = 0; i<5; ++i) {
            for(int j = 0; j<5; ++j) {
                if( i==0 && j==0)
                    continue;
                cin>>arr[i][j];
            }
        }

        cout<<get_max(arr)<<endl;
    }
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值