注解
1、状态压缩:n个团体,每个团体选或者不选(0或者1),压缩成二进制,枚举从1 到 2的n次方 的状态。
2、针对每个状态,计算是否为获胜联盟。如果是,依次枚举此子集中的每个选中的元素,将其取出,看剩下的是否还是获胜联盟。如果不是,则此元素的关键加入者次数加一。暴力循环所有的状态,即可获得每个小团体的权利指数。
代码
#include <iostream>
#include <cstring>
#include <cmath>
using namespace std;
int main() {
int T;
scanf("%d", &T);
for(int i=0; i<T; i++) {
int n;
scanf("%d", &n);
int a[n+1];
int b[n+1];
memset(b, 0, sizeof(b));
int sum = 0;
for(int j=1; j<=n; j++) {
scanf("%d", &a[j]);
sum += a[j];
}
int end = pow(2, n);
for(int j=1; j<end; j++) {
int t = j;
int ss = 0;
for(int k=1; k<=n; k++) {
int tmp = t&1;
t = t>>1;
if(tmp) {
ss += a[k];
}
}
if(ss>sum/2) {
t = j;
for(int k=1; k<=n; k++) {
int tmp = t&1;
t = t>>1;
if(tmp) {
if(ss-a[k]<=sum/2) {
b[k]++;
}
}
}
}
}
printf("%d", b[1]);
for(int j=2; j<=n; j++){
printf(" %d", b[j]);
}
printf("\n");
}
return 0;
}