uva 435 Block Voting

原题:
Different types of electoral systems exist. In a block voting system the members of a party do not
vote individually as they like, but instead they must collectively accept or reject a proposal. Although a party with many votes clearly has more power than a party with few votes, the votes of a small party can nevertheless be crucial when they are needed to obtain a majority. Consider for example the following five-party system:
这里写图片描述
Coalition {A,B} has 7 + 4 = 11 votes, which is not a majority. When party C joins coalition {A,B},
however, {A,B,C} becomes a winning coalition with 7+4+2 = 13 votes. So even though C is a small
party, it can play an important role.As a measure of a party’s power in a block voting system, John F. Banzhaf III proposed to use the power index. The key idea is that a party’s power is determined by the number of minority coalitions that it can join and turn into a (winning) majority coalition. Note that the empty coalition is also a minority coalition and that a coalition only forms a majority when it has more than half of the total number of votes. In the example just given, a majority coalition must have at least 13 votes.
In an ideal system, a party’s power index is proportional to the number of members of that party.
Your task is to write a program that, given an input as shown above, computes for each party its
power index.
Input
The first line contains a single integer which equals the number of test cases that follow. Each of the following lines contains one test case.The first number on a line contains an integer P in [1 … 20] which equals the number of parties for that test case. This integer is followed by P positive integers, separated by spaces. Each of these integers represents the number of members of a party in the electoral system. The i-th number represents party number i. No electoral system has more than 1000 votes.
Output
For each test case, you must generate P lines of output, followed by one empty line. P is the number of parties for the test case in question. The i-th line (i in [1…P]) contains the sentence:
party i has power index I where I is the power index of party i.
Sample Input

3
5 7 4 2 6 6
6 12 9 7 3 1 1
3 2 1 1
Sample Output

party 1 has power index 10
party 2 has power index 2
party 3 has power index 2
party 4 has power index 6
party 5 has power index 6

party 1 has power index 18
party 2 has power index 14
party 3 has power index 14
party 4 has power index 2
party 5 has power index 2
party 6 has power index 2

party 1 has power index 3
party 2 has power index 1
party 3 has power index 1
中文:

给你n个数,现在要计算每个数的“指数”。假设这个数是a,所有的数的和是sum,那么除了a意外的所有的数进行组合,组得到的和在不超过sum/2的的情况下加上这个数a,那么a的指数就+1。如样例一里面,
7的指数是10,除了7以外,剩下的数进行组合有2^4=16种组合,其中有10种组合满足和小于13且加上7大于13。现在让你找出每个数的指数。

#include <bits/stdc++.h>
using namespace std;
int dp[1<<20+1];
int vote[21],ans[21];
int main()
{
    ios::sync_with_stdio(false);
    int n,t,tot,half;
    cin>>t;
    while(t--)
    {
        cin>>n;
        tot=0;
        memset(ans,0,sizeof(ans));
        memset(dp,0,sizeof(dp));
        for(int i=1;i<=n;i++)
        {
            cin>>vote[i];
            tot+=vote[i];
        }
        half=(tot)/2;
        for(int s=1;s<(1<<n);s++)
        {
            for(int i=1;i<=n;i++)
            {
                if(s>>(i-1)&1)
                    dp[s]=dp[s&~(1<<(i-1))]+vote[i];
            }
        }
        for(int s=0;s<(1<<n);s++)
        {
            for(int i=1;i<=n;i++)
            {
                if(!(s>>(i-1)&1))
                {
                    if(dp[s]+vote[i]>half&&dp[s]<=half)
                        ans[i]++;
                }
            }
        }
        for(int i=1;i<=n;i++)
            cout<<"party "<<i<<" has power index "<<ans[i]<<endl;
        cout<<endl;
    }
    return 0;
}

解答:
很简单的状态压缩动态规划题目,很适合练手。一共有20个数,所以状态可以是2^20次幂个。设置dp[s]为集合s时数的和,如果集合s不超过总和的一半,且集合s当中没有第i个数。那么dp[s∪i]=dp[s]+vote[i]
其中vote[i]为第i个数是多少。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值