Partition problem

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.

给定2N个人,你需要去把他们分配到红队或者白队里,使得每一个队伍都有n个人,以及仇恨值最大

Total competitive value is the summation of competitive value of each pair of people in different team.

仇恨值就是在不同队伍里每一对人的仇恨值之和

The equivalent equation is ∑2Ni=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 vijvij is the j-th value of the i-th line which indicates the competitive value of person i and person j.

* 1≤N≤141≤N≤14
* 0≤vij≤1090≤vij≤109
* vij=vjivij=vji

输出描述:

Output one line containing an integer representing the maximum possible total competitive value.

本题可以直接使用DFS,策略是在搜索中分别用数组模拟两个队伍,并模拟此人加入队伍,再计算仇恨值。

//#include<pch.h>
#include <iostream>
#include <cstdio>
#include <bits/stdc++.h>
#include <map>
#include <algorithm>
#include <stack>
#include <iomanip>
#include <cstring>
#include <cmath>
#define DETERMINATION main
#define lldin(a) scanf_s("%lld", &a)
#define println(a) printf("%lld\n", a)
#define reset(a, b) memset(a, b, sizeof(a))
const int INF = 0x3f3f3f3f;
using namespace std;
const double PI = acos(-1);
typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
const int mod = 1000000007;
const int tool_const = 19991126;
const int tool_const2 = 33;
inline ll lldcin()
{
    ll tmp = 0, si = 1;
    char c;
    c = getchar();
    while (c > '9' || c < '0')
    {
        if (c == '-')
            si = -1;
        c = getchar();
    }
    while (c >= '0' && c <= '9')
    {
        tmp = tmp * 10 + c - '0';
        c = getchar();
    }
    return si * tmp;
}
///Untersee Boot IXD2(1942)
/**Although there will be many obstructs ahead,
the desire for victory still fills you with determination..**/
/**Last Remote**/
ll totality1, totality2,finans;
ll n;
ll secq1[50], secq2[50],relationships[50][50];
void dfs(ll tmpans, ll current,ll limit1,ll limit2)
{
    if (limit1 == n && limit2 == n)//如果满足条件
    {
        finans = max(finans, tmpans);
        return;
    }
    if (limit1 < n)
    {
        ll increment = 0;
        secq1[++limit1] = current;//模拟加入队伍
        for (int i = 1; i <= limit2; i++)
            increment += relationships[current][secq2[i]];//加入队伍后带来的仇恨值增量
        dfs(tmpans + increment, current + 1, limit1, limit2);//继续
        limit1--;//将此人逐出队伍,即回溯
    }
    if (limit2 < n)
    {
        ll increment = 0;
        secq2[++limit2] = current;
        for (int i = 1; i <= limit1; i++)
            increment += relationships[current][secq1[i]];
        dfs(tmpans + increment, current + 1, limit1, limit2);
        limit2--;
    }
}
int DETERMINATION()
{
    ios::sync_with_stdio(false);
    cin.tie(0), cout.tie(0);
    cin >> n;
    n <<= 1;
    for (int i = 1; i <= n; i++)
        for (int j = 1; j <= n; j++)
            cin >> relationships[i][j];
    n >>= 1;
    dfs(0, 1, 0, 0);
    cout << finans << endl;
    return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值