`

【二进制状态压缩+子集枚举/新增深搜】HDU 1557 权利指数

阅读更多
http://acm.hdu.edu.cn/showproblem.php?pid=1557


Problem Description
在选举问题中,总共有n个小团体,每个小团体拥有一定数量的选票数。如果其中m个小团体的票数和超过总票数的一半,则此组合为“获胜联盟”。n个团体可形成若干个获胜联盟。一个小团体要成为一个“关键加入者”的条件是:在其所在的获胜联盟中,如果缺少了这个小团体的加入,则此联盟不能成为获胜联盟。一个小团体的权利指数是指:一个小团体在所有获胜联盟中成为“关键加入者”的次数。请你计算每个小团体的权利指数。

Input
输入数据的第一行为一个正整数T,表示有T组测试数据。每一组测试数据的第一行为一个正整数n(0<n<=20)。第二行有n个正整数,分别表示1到n号小团体的票数。

Output
对每组测试数据,在同一个行按顺序输出1到n号小团体的权利指数。

Sample Input
2
1
10
7
5 7 4 8 6 7 5

Sample Output
1
16 22 16 24 20 22 16


#include <iostream>
using namespace std;

int main()
{
	int t, n, a[25], i, key[25], k, total, ans[25];
	scanf ("%d", &t);
	while (t--)
	{
		memset (ans, 0, sizeof(ans));
		total = 0;
		scanf ("%d", &n);
		for (i = 0; i < n; i++)
			scanf ("%d", a+i), total += a[i];
		total /= 2;    //总票数的一半【写成total = (total+1)/2 会错……】
		//枚举子集【1】~【2的n次方-1】
		int maxs = 1 << n;
		for (i = 1; i < maxs; i++)
		{
			k = 0;
			int tp = i, j = 0, sum = 0;
			while (tp)
			{
				if (tp & 1)//tp的二进制从左往右数第j位是1,则认为a[j]入了集合
					key[k++] = j, sum += a[j];
				//记住入了集合的a的元素编号j,并累加票数
				tp >>= 1;    //tp的二进制往右移动,即消去二进制最后一位
				j++;
			}
			if (sum > total)    //如果团体的票数超过总票数的一半
				for (j = 0; j < k; j++)
					if (sum - a[key[j]] <= total)
						ans[key[j]]++;
	//如果没了a[key[j]]就不行,则编号为key[j]的元素为“关键加入者”,该元素权利指数+1
		}
		printf ("%d", ans[0]);
		for (i = 1; i < n; i++)
			printf (" %d", ans[i]);
		printf ("\n");
	}
	return 0;
}


深搜:
#include <iostream>
using namespace std;

int con[25], ans[25], total, n, a[25], key;    //con存放a中元素编号
bool visited[25];

void dfs (int x, int sum, int times)//x是元素编号,sum是临时和,times是con中元素个数
{
    if (times == key)
    {
        if (sum > total)
            for (int i = 0; i < times; i++)
                if (sum - a[con[i]] <= total)
                    ans[con[i]]++;
        return ;
    }
    for (int i = x + 1; i < n; i++)
    {
        con[times] = i;
        dfs (i, sum+a[i], times+1);
    }
}

int main()
{
    int t, i;
    scanf ("%d", &t);
    while (t--)
    {
        scanf ("%d", &n);
        total = 0;
        for (i = 0; i < n; i++)
            scanf ("%d", a+i), total += a[i];
        total /= 2;
        memset (ans, 0, sizeof(ans));
        for (key = 1; key <= n; key++)    //枚举获胜联盟中团体个数
        {
            memset (visited, false, sizeof(visited));
            visited[0] = true;
            dfs (-1, 0, 0);
        }
        for (i = 0; i < n - 1; i++)
            printf ("%d ", ans[i]);
        printf ("%d\n", ans[n-1]);
    }
    return 0;
}
2
6
分享到:
评论
2 楼 基德KID.1412 2011-08-02  
breakallerror 写道
木仔细看,貌似还是一种暴力

其实就是暴力
1 楼 breakallerror 2011-08-02  
木仔细看,貌似还是一种暴力

相关推荐

    子集(二进制序列枚举法)1

    子集(二进制序列枚举法)是一种解决数组子集问题的方法,它涉及到计算机科学中的位操作和组合数学。给定一个互不相同的整数数组 `nums`,任务是生成所有可能的子集,包括空集,并且不包含重复的子集。问题的关键...

    基于二进制作用模糊子集推理单片机模糊控制的发展.doc

    【基于二进制作用模糊子集推理的单片机模糊控制】是一种将模糊逻辑理论与单片机技术相结合的方法,用于提升控制系统的智能化和实时性。单片机模糊控制器分为两类,一类是硬件实现的模糊单片机控制器,利用模糊逻辑...

    使用二进制排除不符合条件n位数

    总的来说,使用二进制排除不符合条件的n位数是一种巧妙的策略,它利用了二进制数的性质,使得在解决组合问题时能够有效地避免重复,并且提供了一种高效的方法来枚举所有可能的子集。在编程和算法设计中,这样的思维...

    ASCII码与6bit二进制互相转换

    将6bit二进制转换为ASCII码,将ASCII码转换为6bit二进制

    论文研究-基于二进制的关联规则挖掘算法.pdf

    将二进制引入关联规则求解中,充分利用二进制操作方便、运算速度快、节省空间的优势。在求解事务项集真子集和支持度时,对事务数据库中相同事务只求解一次,并给出了真子集的具体求解算法。本算法一次扫描数据库可以...

    POJ1014-Dividing【DFS】【多重背包+二进制优化】

    在给出的文件列表中,“POJ1014-Dividing【多重背包+二进制优化】.cpp”和“POJ1014-Dividing【DFS】.cpp”很可能是两份不同的C++代码实现,分别展示了如何结合多重背包和二进制优化以及如何利用DFS来解决问题。...

    第4章 状态压缩类动态规划-2020.06.08.pdf

    - 而在状态压缩类动态规划中,通过将这些变量的状态进行二进制编码,可以使用一个整数来表示所有变量的状态组合。 - 这种编码方式被称为“状态压缩”。 2. **位操作**: - 状态压缩依赖于二进制下的位操作(如与...

    使用GA的二进制特征选择

    在二进制特征选择中,每个候选特征子集都可以用一个二进制编码来表示,其中每一位对应一个特征是否被选中。以下是使用GA进行二进制特征选择的一般步骤: 编码:将特征选择问题转化为一个二进制编码的优化问题。假设...

    【特征选择】基于蜻蜓算法实现二进制特征选择问题附matlab代码(DragonflyAlgorithm,DA) 发资源.zip

    MATLAB代码会根据蜻蜓算法的规则,对这些二进制向量进行操作,逐步优化特征子集。这可能包括使用交叉验证来评估模型性能,以及设置停止条件,如达到预设的迭代次数或性能阈值。 在资源包中,可能包含以下文件: 1. ...

    tinybits:我在所有地方(C,C ++)一直使用的小片段和有用的代码片段

    二分法二进制搜索 C ++ 二分法二进制搜索 C 构建宏 C 调试宏 C ++ 延迟宏,转到样式 C ++ 目录清单 C 小型YAML子集配置文件解析器 重击 双重bash /批处理文件 C 字节顺序转换 C 错误处理 C 紧...

    【特征选择】基于灰狼算法实现二进制特征选择问题附matlab代码.zip

    本资源提供的是一种基于灰狼优化算法(Grey Wolf Optimization, GWO)实现的二进制特征选择方法,适用于解决特征冗余和不相关的问题。 灰狼算法是一种模拟自然界灰狼群捕食行为的优化算法,具有较强的全局搜索能力...

    C/C++语言编程安全子集

    C/C++语言编程安全子集

    计算机各种进制转换练习题(附答案).pdf

    - 任意的八进制有限小数也一定是二进制有限小数,因为八进制是二进制的子集。 - 任意的十六进制有限小数也是十进制有限小数,因为十六进制是二进制的子集。 10. 二进制数转换: - 1111111111转换为十进制是1023...

    PASCAL语言子集(PL/0)编译器的设计与实现

    在IT领域,编译器是计算机科学中的一个重要组成部分,它将高级编程语言转换为机器可理解的二进制代码。本项目聚焦于PASCAL语言的一个子集——PL/0的编译器设计与实现。PASCAL是一种结构化编程语言,而PL/0是其简化...

    【特征选择】基于原子搜索算法实现二进制特征选择问题附matlab代码.zip

    在这个项目中,我们将深入探讨如何利用原子搜索算法进行二进制特征选择,并结合MATLAB代码进行实践。 一、特征选择的重要性 特征选择对机器学习模型的影响显著,主要体现在以下几个方面: 1. **降低计算复杂度**:...

    10进制与16进制浮点数转换

    6. **16进制到二进制再到10进制**:同样,16进制浮点数先转换为二进制,然后根据IEEE 754的规则解析二进制流,包括符号位、指数位和尾数位,最后计算出10进制值。 7. **转换工具的使用**:在提供的“浮点数转换工具...

    accsii编码表,十进制,二进制

    - **十六进制**:十六进制是二进制的一种压缩形式,用两位十六进制数可以表示一个字节的数据。对于ASCII编码,只需关注前两位十六进制数即可。 #### 3. ASCII编码表详解 ASCII编码表包含了所有128个标准字符的编码...

    状态压缩DP.pdf

    常用的方法是利用二进制位来表示不同的状态,比如在一个有n个元素的集合中,可以用n位的二进制数来表示不同的子集,每一位代表集合中的一个元素是否存在。 #### 2. 复杂度分析 对于状态压缩DP,状态的数量通常是...

Global site tag (gtag.js) - Google Analytics