比赛组队-Java-2017百度秋招

本文介绍了一个比赛组队问题的解决方案,通过递归寻找最优组合,实现团队水平的最大化及统计最优方案数量。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

package 百度;

import java.util.Scanner;

/**
 * 题目描述: 为活跃公司文化,公司计划组织一场比赛,让员工一展才艺。现有n个员工,欲选出不少于k人组成一支队伍,1<=n< =12,1<=k<=n。
 * 每个员工有个value值,表示其对队伍水平的贡献,-1000<=value<=1000,给出一个矩阵对角线为0的对称矩阵A,
 * A[i][j]表示i,j同在队伍中时对队伍水平的贡献,为取得最好成绩,公司领导希望知道水平最高的组队方式能够达到的水平和组队方案数。
 * 
 * 
 * 输入 第一行为测试样例组数Te(Te<=100)。每组测试样例的第一行是两个数n,k,第二行为n个数,表示每个人对队伍水平的贡献值,
 * 接下来有n行,每行有n个数,表示构成矩阵A的元素。 样例输入 1 2 1 100 -5 0 10 10 0 输出
 * 每组测试样例输出一行,分别为能够达到的最高水平值和组队方案数。 样例输出 105 1
 * 
 * @author 崔洪振367
 * @version 创建时间:2017年5月15日 下午4:40:21
 * 
 * 解题思路:递归找到所有组合的情况,然后就是比较每种情况下的组队水平值,并统计此种情况下有多少种形式。
 */
public class Q2017秋招_比赛组队 {

	static int a[] = new int[100];
	static int cnt;
	static int max;
	static int[] values;
	static int[][] conPower;

	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		while (sc.hasNext()) {
			int T = sc.nextInt();// T组队
			for (int t = 0; t < T; t++) {
				// sc.nextLine();
				int n = sc.nextInt();// n个人
				int k = sc.nextInt();// 从n个人中选择k个人
				if (k > n) {
					return;
				}
				// sc.nextLine();
				values = new int[n];// 个人能力
				conPower = new int[n][n];// 组合后的能力
				for (int i = 0; i < n; i++) {
					values[i] = sc.nextInt();
				}
				sc.nextLine();
				for (int i = 0; i < n; i++) {
					for (int j = 0; j < n; j++) {
						conPower[i][j] = sc.nextInt();
					}
					// sc.nextLine();
				}

				// n个人中选k个人的组合情况
				boolean[] p = new boolean[n];
				max = Integer.MIN_VALUE;
				cnt = 0;
				core(p, 0, k, n);
				System.out.println(max + " " + cnt);

			}
		}

	}

	private static void core(boolean[] p, int i, int k, int n) {
		if (i == n) {
			int kk = 0;
			for (boolean flag : p) {
				if (flag)
					kk++;
			}
			if (kk < k) {
				return;
			}
			int value = 0;
			for (int j = 0; j < n; j++) {
				if (p[j]) {
					value += values[j];
				}
			}
			for (int j = 0; j < n; j++) {
				for (int l = j + 1; l < n; l++) {
					if (p[j] && p[l]) {
						value += conPower[j][l];
					}
				}
			}
			if (value > max) {
				max = value;
				cnt = 1;
			} else if (value == max) {
				cnt++;
			}
			return;
		}
		p[i] = true;
		core(p, i + 1, k, n);
		p[i] = false;
		core(p, i + 1, k, n);
	}

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值