2019牛客多校第二场F

题目描述

Given 2N people, you need to assign each of them into either red team or white team such that each team consists of exactly N people and the total competitive value is maximized.

Total competitive value is the summation of competitive value of each pair of people in different team.
The equivalent equation is ∑2Ni=1∑2Nj=i+1(vij if i-th person is not in the same team as j-th person else 0)∑i=12N∑j=i+12N(vij if i-th person is not in the same team as j-th person else 0)

输入描述:

The first line of input contains an integers N.

Following 2N lines each contains 2N space-separated integers vij is the j-th value of the i-th line which indicates the competitive value of person i and person j.

  • 1≤N≤14
  • 0≤vij≤109
  • vij=vji 输出描述:
    Output one line containing an integer representing the maximum possible total competitive value.

示例1

输入

1
0 3
3 0

输出

3

本题的意思大致上是指:
将2N个人分为为两个小队,每队N人,每两个人之间都有一个竞争值,当两人分在一个队伍时,当然没有竞争,两者竞争值为0,不在一个队伍时,他们之间的竞争值该是多少就是多少。最后求最大竞争值总和分组的竞争值(即怎样分组时竞争值总和最大,输出最大值)。

输入:N,2N*2N的矩阵,其中矩阵中i行j列的值和j行i列的竞争值相等。

思路:模拟所有情况,求出最大值。

#include"iostream"
using namespace std;
typedef long long ll;
ll N,rn = 0 ,bn = 0,a[30][30],r[30],b[30],ans = 0;//a为竞争值数组,r,b分别存两个队伍中的人,rn,bn分别为对应队伍人数
void dfs(ll n,ll sum){
    if(rn==N||bn==N){//当一个队伍分好,另一个队伍也默认分好了,就可以直接求出竞争值,不用继续分
        if(rn==N){
            for(ll i = n;i <= 2*N;i++)
                for(ll j = 1;j <= rn;j++)
                    sum+=a[i][r[j]];
          }
        else{
            for(ll i = n;i <= 2*N;i++)
                for(ll j = 1;j <= bn;j++)
                    sum+=a[i][b[j]];
         }
        ans = max(ans,sum);
        return;
    }
    r[++rn] = n;//注意在n分在r队后,再讨论将n分在b队前,要还原
    ll temp = 0;
    for(ll i = 1;i <= bn;i++)
        temp+=a[n][b[i]];
    dfs(n+1,sum+temp);
    temp = 0;//还原
    rn--;//还原
    b[++bn] = n;
    for(ll i = 1;i <= rn;i++)
        temp+=a[n][r[i]];
    dfs(n+1,sum+temp);
    bn--;
}
int main(){
    cin >> N;
    for(ll i = 1;i <= 2*N;i++)
        for(ll j = 1;j <= 2*N;j++)
            cin >> a[i][j];
            dfs(1,0);
    cout << ans;
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值