题目链接: 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 }