权利指数(hdu 1557)

此题链接单击这里

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

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

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

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

<2^7=128二进制子集
000
115
2107
3115,7
571110015,8,6,7
1271111115,7,4,8,6,7,5
//关键代码

void funt(int n,int s)
{
    for(int i=0;i<n;i++)
        if(s&(1<<i)) //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<<n);i++)//i<(i<<n) -> i<128
        funt(n,i);
}

附题目代码

#include <iostream>
#include <cstring>
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<<' '<<c[i];
        cout<<endl;
    }
    return 0;
}

有问题联系企鹅791267032
邮箱地址….wutanrong@Hotmail.com

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值