权利指数(hdu 1557)

此题链接单击这里

=================

此题只要枚举出所有子集即可AC~~~~~好吧,关键就是怎么枚举子集。。。
做此题之前根本不知道怎么枚举子集,把紫书(刘汝佳著)子集生成一节看几遍,最后用二进法做此题(就看懂了这个~~~)。

二进制法枚举子集:
n个数有2^n个子集,每个子集对应一个二进数,每位二进制对应一个数。二进制的位权为0表示子集不包含那个数,二进制的位权为1表示子集包含那个数。

案例
2
1
10
7
5 7 4 8 6 7 5
取n=7

<2^7=128 二进制 子集
0 0 0
1 1 5
2 10 7
3 11 5,7
57 111001 5,8,6,7
127 111111 5,7,4,8,6,7,5
//关键代码

void funt(int n,int s)
{
    for(int i=0;iif(s&(1<//n的子集共有2^n个,若s=13(1101),刚i=0,2,3时输出
                     //13&(1<<0)->13&1  ==1
                     //13&(1<<2)->13&4  ==1
                     //13&(1<<3)->13&8  ==1
                     // 反例13&(1<<4)->13&16 ==0
           printf("%d",i);
        printf("\n");

}
int main()
{
    int n=7;
    for(int i=0;i<(1<//i<(i< -> i<128
        funt(n,i);
}

附题目代码

#include 
#include 
using namespace std;
int k;
int a[20];
int b[20];
int c[20];
long sum;
int ave;
void funt(int n, int s)
{
    sum = 0;
    memset(b, 0, sizeof(b));
    for (int i = 0; i < n; i++)
        if (s&(1 << i))
        {
            sum += a[i];
            b[i] = 1;
        }
    if (sum >ave)
        for (int i = 0; i < n; i++)
            if (b[i] == 1 && (sum - a[i])<=ave)
                c[i]++;
}

int main()
{
    int T;
    cin >> T;
    while (T--)
    {
        memset(c, 0, sizeof(c));
        int n;
        cin >> n;
        ave = 0;
        for (int i = 0; i < n; i++)
        {
            cin >> a[i];
            ave += a[i];
        }
        ave = ave / 2;
  //      if (ave % 2 != 0)
  //          ave++;
        for (int i = 0; i < (1 << n); i++)
            funt(n, i);
        int loge=1;
        for (int i = 0; i < n; i++)
            if(loge)
               {
                   cout << c[i];
                   loge=0;
               }
            else
                cout<<' '<cout<return 0;
}

有问题联系企鹅791267032
邮箱地址…[email protected]

你可能感兴趣的:(权利指数(hdu 1557))