2019牛客多校训练营第二场 F. Partition problem

题目链接

题目描述

Given 2 N 2N 2N people, you need to assign each of them into either red team or white team such that each

team consists of exactly N N 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 ∑ i = 1 2 N ∑ j = i + 1 2 N v i j \sum_{i=1}^{2N}\sum_{j=i+1}^{2N}v_{ij} i=12Nj=i+12Nvij(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 N N.

Following 2 N 2N 2N lines each contains 2 N 2N 2N space-separated integers v i j v_{ij} vij

  • 1 ≤ N ≤ 14 1\leq N\leq 14 1N14
  • 0 ≤ v i j ≤ 1 0 9 0 \leq v_{ij} \leq 10^9 0vij109
  • v i j = v j i v_{ij}=v_{ji} vij=vji
输出描述

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

示例1
输入
1
0 3
3 0
输出
3
题目大意

一只球队总共有 2 × n 2\times n 2×n个队员,每两个队员之间都有一个竞争值,将 2 × n 2\times n 2×n个队员分成两组,使得不同组队员之间竞争值和最大。

解题思路

拿到这道题的时候就想到了全排列,也就是暴力搜索, N N N最大为14,那么时间复杂度就是 C ( 28 , 14 ) C(28,14) C(28,14),值在 4 e 7 4e7 4e7左右,那么接下来就是计算所有情况下的竞争值总和,如果直接用双层循环来计算的话,时间复杂度 O ( n 2 ) O(n^2) O(n2),即 196 196 196,直接会炸掉,所以不能在得到分组结果之后才进行计算竞争值之和,这样会付出更多的时间代价。而正解应该是一边进行分组,一边进行计算。

AC代码
#include<bits/stdc++.h>
#define _MATH_DEFINES_DEFINED
const int Max_N=1e5+10;
const int mod=998244353;
typedef long long ll;
typedef unsigned long long ull;
using namespace std;
int team[30][30];
int team1[30];
int team2[30];
ll res=0;
int n;
void dfs(int num1,int num2,int pos,ll maxres)
{
	if(pos==2*n)
	{
		res=max(res,maxres);
	}
	if(num1<n)
	{
		team1[num1]=pos;
		ll v=maxres;
		for(int i=0;i<num2;i++)
			v+=team[pos][team2[i]];
		dfs(num1+1,num2,pos+1,v);
	}
	if(num2<n)
	{
		team2[num2]=pos;
		ll v=maxres;
		for(int i=0;i<num1;i++)
			v+=team[pos][team1[i]];
		dfs(num1,num2+1,pos+1,v);
	}
	return ;
}
int main()
{
	cin>>n;
	for(int i=0;i<2*n;i++)
	{
		for(int j=0;j<2*n;j++)
		{
			cin>>team[i][j];
		}
	}
	dfs(0,0,0,0);
	cout<<res<<endl;
}
总结

暴力的题目不能过分依赖 S T L STL STL的函数,手写 d f s dfs dfs并加入优化的过程会得到意想不到的结果。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值