此题链接单击这里
=================
此题只要枚举出所有子集即可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;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