[2016-01-21][HDU][1557]
[2016-01-21][HDU][1557]
- /*************************************************************
- 时间:2016-01-20 20:48:59 星期三
- 题目编号:HDU 1557
- 题目大意:
- 选举投票,每个团体有一定票数,若干个团体可以组成联盟,票数超过一半的联盟为获胜联盟
- 求每个团体的权利指数
- 权利指数:小团体在所有获胜联盟中是 "关键加入者" 的次数
- 关键加入者:少了这个人,联盟就不是获胜联盟
- 方法:
- 二进制枚举
- *************************************************************/
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
|
#include <vector>#include <list>#include <map>#include <set>#include <deque>#include <queue>#include <stack>#include <bitset>#include <algorithm>#include <functional>#include <numeric>#include <utility>#include <sstream>#include <iostream>#include <iomanip>#include <cstdio>#include <cmath>#include <cstdlib>#include <cctype>#include <string>#include <cstring>#include <cstdio>#include <cmath>#include <cstdlib>#include <ctime>using namespace std;int votes[22];int res[22];int main(){ int t; scanf("%d",&t); while(t--){ int n; scanf("%d",&n); int sum = 0; for(int i = 1;i <= n;i++){ scanf("%d",&votes[i]); sum += votes[i]; } memset(res,0,sizeof(res)); int all = (1 << n ); //枚举所有联盟情况 for(int i = 0;i < all;i++){ int tsum = 0; //求和 for(int j = 0;j < n;j++) if(i & (1 << j)) tsum += votes[j+1]; //超过一半? if(tsum*2>sum) //枚举所有团体,看去掉这个团体后会怎么样, for(int j = 0;j < n;j++) if(i & (1 << j)) if((tsum - votes[j+1])*2 <= sum)//无法获胜,对应团体,权利指数+1 res[j+1]++; } for(int i = 1;i<=n;i++) printf("%d%c",res[i],(i+1 <=n?' ':'\n')); } return 0;} |
浙公网安备 33010602011771号