比赛组队

题目链接: http://exercise.acmcoder.com/online/online_judge_ques?ques_id=3372&konwledgeId=40

解题思路: 完全可以通过枚举的思路来计算每种组合的得分。这里我们用整数的二进制位来表示,一个选手是否在一个组合中出现。例如,对于3个人, 5=101b,就表示第一个人和第三个人的组合。这样只需要对所有的组合求和就可以了。还有需要注意,题目中每个人的能力可以是负的。

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 
 4 typedef long long LL;
 5 const int MAXN = 100005;
 6 const LL MOD7 = 1e9+7;
 7 
 8 int lowbit(int x)
 9 {
10     return x&(-x);
11 }
12 
13 int calBits(int x)
14 {
15     int ans=0;
16     while (x)
17     {
18         x-=lowbit(x);
19         ++ans;
20     }
21     return ans;
22 }
23 
24 int a[15][15];
25 int b[15];
26 int n,K;
27 
28 void solve()
29 {
30     int maxValue=-1000*n;
31     int cnt=0;
32     int allState=(1<<n);
33     for (int state=1;state<allState;++state)
34     {
35         if (calBits(state)<K) continue;
36         int value=0;
37         for (int i=0;i<n;++i)
38         {
39             if (state&(1<<i))
40             {
41                 value+=b[i];
42                 for (int j=i+1;j<n;++j)
43                 {
44                     if (state&(1<<j))
45                         value+=a[i][j];
46                 }
47             }
48         }
49         if (value > maxValue) { maxValue=value; cnt=1;}
50         else if (value==maxValue) ++cnt;
51     }
52     printf("%d %d
", maxValue, cnt);
53 }
54 
55 int main()
56 {
57 #ifndef ONLINE_JUDGE
58     freopen("test.txt","r",stdin);
59 #endif // ONLINE_JUDGE
60     int Case;
61     scanf("%d",&Case);
62     while (Case--)
63     {
64         scanf("%d%d",&n,&K);
65         for (int i=0;i<n;++i) scanf("%d",&b[i]);
66         for (int i=0;i<n;++i)
67             for (int j=0;j<n;++j)
68             scanf("%d",&a[i][j]);
69         solve();
70     }
71     return 0;
72 }
原文地址:https://www.cnblogs.com/djingjing/p/8931784.html