题目描述
为活跃公司文化,公司计划组织一场比赛,让员工一展才艺。现有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 |
输出 每组测试样例输出一行,分别为能够达到的最高水平值和组队方案数。 |
样例输出 105 1 |
时间限制C/C++语言:1000MS其它语言:3000MS |
内存限制C/C++语言:65536KB其它语言:589824KB |
#include <iostream>
#include <vector>
#include <limits.h>
using namespace std;
void evaluate(const vector<bool>& res, const vector<int>& value,
const vector<vector<int>>& A, const int& k, int* valueSum, int* num) {
int tempSum = 0, attendNum = 0;
for (int i = 0; i < res.size(); i++)
{
if (res.at(i))
attendNum++;
}
if (attendNum < k)
return;
for (int i = 0; i < res.size(); i++)
{
if (res.at(i)){
tempSum += value.at(i);
for (int j = i - 1; j >= 0; j--)
{
if (res.at(j))
tempSum += A.at(j).at(i);
}
}
}
if (tempSum > *valueSum)
{
*valueSum = tempSum;
*num = 1;
}
else if (tempSum == *valueSum) {
(*num)++;
}
}
void pick(vector<bool> res, int i, const int& k, const vector<int>& value,
const vector<vector<int>>& A, int* valueSum, int* num) {
if (i >= res.size()) {
evaluate(res, value, A, k, valueSum, num);
return;
}
else
{
res.at(i) = true;
pick(res, i + 1, k, value, A, valueSum, num);
res.at(i) = false;
pick(res, i + 1, k, value, A, valueSum, num);
}
}
int main() {
int Te, n, k;
cin >> Te;//测试样例数量
for (int i = 0; i < Te; i++)
{
cin >> n >> k;
vector<int> value(0, n);
vector<vector<int>> A(n, vector<int>(n));
int temp = 0;
for (int j = 0; j < n; j++)
{
cin >> temp;
value.push_back(temp);
}
for (int j = 0; j < n; j++)
{
for (int z = 0; z < n; z++)
{
cin >> temp;
A.at(j).at(z) = temp;
}
}
vector<bool> res(n, false);
int valueSum = INT_MIN, num = 0;
pick(res, 0, k, value, A, &valueSum, &num);
cout << valueSum << " " << num << endl;
}
//system("pause");
return 0;
}