UVA 11825 状态压缩DP+子集思想

很明显的状态压缩思想了。把全集分组,枚举每个集合的子集,看一个子集是否能覆盖所有的点,若能,则f[s]=max(f[s],f[s^s0]+1)。即与差集+1比较。

这种枚举集合的思想还是第一次遇到,果然太弱了。。。。~~~~

其中枚举集合

for(s0=s;s0;s0=(s0-1)&s)

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>

using namespace std;

const int N=16;
int pt[1<<N];
int cover[1<<N];
int f[1<<N];

int main(){
	int n,x,icase=0;
	while(scanf("%d",&n),n){
		int c,s;
		for(int i=0;i<n;i++){
			scanf("%d",&c);
			s=(1<<i);
			for(int k=0;k<c;k++){
				scanf("%d",&x);
				s|=(1<<x);
			}
			pt[i]=s;
		}
		memset(cover,0,sizeof(cover));
		for(int i=0;i<(1<<n);i++){
			for(int j=0;j<n;j++){
				if((1<<j)&i){
					cover[i]|=pt[j];
				}
			}
		}
		memset(f,0,sizeof(f));
		for(int s=0;s<(1<<n);s++){
			f[s]=0;
			for(int s0=s;s0;s0=(s0-1)&s){
				if(cover[s0]==(1<<n)-1) f[s]=max(f[s],f[s0^s]+1);
			}
		}
		printf("Case %d: %d\n",++icase,f[(1<<n)-1]);
	}
	return 0;
}

  

时间: 2025-01-08 22:41:16

UVA 11825 状态压缩DP+子集思想的相关文章

uva 11795(状态压缩dp)

题意:有一个机器人要杀死其他n(1 <= n <= 16)个机器人,他自己配备了一个武器,并且给出了这个武器能杀死的敌人,如101表示他能杀死第1和第3个敌人,这样他就能得到第1和第3号敌人的武器,从而杀死更多的敌人,问他杀死所有的敌人的方法数. 题解:因为敌人数最多是16个,很容易想到应该是状态压缩dp,可以用f[S]表示状态S下进制位为1的敌人全被杀死的方案数,那么结果就是f[(1 << n) - 1],如果拿掉了状态S中的杀死第j个人能得到的武器,剩下的人如果能杀死第j个人,

uva 1252(状态压缩dp)

题意:有n个二进制串,长度都是m且都不相同,问最少询问多少个问题可以把这n个串完全区分开. 题解:1<=m<=11,从这个范围就可以推测是状态压缩,那么dp肯定要有一维表示提问的问题,然后另一位就是根据提出的问题把串分类,一种是符合提出的问题的状态,另一种不符合.这样f[i][j]表示在问了问题i的状态下答案是状态j时还要提出多少个问题才能把所有串区分开. 如果找到在问题i下和答案j相同的串只有1串或没有,说明f[i][j]=0不需要再提问就已经区分开了,否则就要再提问问题,把之前问题i的位上

uva 10817 状态压缩DP

题意: 有S个课程要教, 学校本来有m个教师 给出工资和所教课程编号  (在职教师不能辞退) 来应聘的有n个教师 给出工资和所教课程编号 问保证每个课程都有两个老师可以教的前提下,最少发多少工资 思路: 水题: 总共最多只有8个课程,状态压缩 d[i][s1][s2] 表示当前状态下,有一个老师教的课程是s1,有两个或两个人以上教的课程是s2 转移就是当前教师选或不选,对应的转移到下一个(i+1个)教师的决策即可. code: #include<cstdio> #include<iost

UVA 1252-Twenty Questions(状态压缩DP+子集枚举)

题目大意:有n个物品,每个物品有m个特征,每个物品的每个特征都可能有或没有,现在假定某个物品,通过询问某些特征来确定这个物品,问最多需要多少次就可以确定物品. 每次询问之后可能根据答案不同来采取不同的进一步询问的策略. 用d[S][S0]表示目前询问了S,得到的回答是S0(即那个物品在S中有S0这些特征),最少还需询问多少次.枚举下一次询问的特征完成递推.最终d[0][0]就是答案.S0显然是S的一个子集.下一次询问的特征不是S已有的特征.如果对于某个d[S][S0]只有一个物品满足,那么此时值

UVA 11825 - Hackers&amp;#39; Crackdown 状态压缩 dp 枚举子集

UVA 11825 - Hackers' Crackdown 状态压缩 dp 枚举子集 ACM 题目地址:11825 - Hackers' Crackdown 题意: 有一个由编号0~n-1的n台计算机组成的网络,一共同拥有n种服务,每台计算机上都执行着所有服务,对于每台计算机,你能够选择停止一项服务,这个行为会导致与这台计算机和与他相连的其它计算机上的这项服务都停止(原来已经停止的继续保持停止状态). 求最多能使多少个服务瘫痪(即没有不论什么一台计算机在执行这项服务). 分析: 题目说白了.就

uva 11825 Hackers&#39; Crackdown(状态压缩DP)

Hackers' Crackdown Input: Standard Input Output: Standard Output   Miracle Corporations has a number of system services running in a distributed computer system which is a prime target for hackers. The system is basically a set of N computer nodes wi

uva 11825 ,Hacker&#39;s Crackdown 状态压缩 dp

// uva 11825 Hacker's Crackdown // // 题目意思看了很久才看懂,有n台计算机,有n种服务,每台计算机上运行所有 // 的服务,并且其中有的计算机与某些计算机相互邻接,对于每台计算机, // 你可以选择一项服务,停止这项服务,则与它邻接的计算机的该服务也停止了 // 你的目的是让经量多的服务完全瘫痪 // // 换而言之,这个问题就是在n个集合中(p[1]....p[n])分成尽量多的组数,使得每组 // 的并集等于全集(即所有的n台电脑都停止)... // /

11825 - Hackers&#39; Crackdown 状态压缩 dp 枚举子集

11825 - Hackers' Crackdown 状态压缩 dp 枚举子集 ACM 题目地址:11825 - Hackers' Crackdown 题意: 有一个由编号0~n-1的n台计算机组成的网络,一共有n种服务,每台计算机上都运行着全部服务,对于每台计算机,你可以选择停止一项服务,这个行为会导致与这台计算机和与他相连的其他计算机上的这项服务都停止(原来已经停止的继续保持停止状态).求最多能使多少个服务瘫痪(即没有任何一台计算机在运行这项服务). 分析: 题目说白了,就是: 把n个集合p

UVa 11825 - Hackers&#39; Crackdown DP, 枚举子集substa = (substa - 1)&amp;sta 难度: 2

题目 https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=2925 题意 n个节点,每个节点都有完全相同的n项服务. 每次可以选择一个节点,破坏该节点和相邻节点的某项服务. 问最多能完全破坏多少服务? 思路 如刘书, 直接枚举状态的子集 注意元素个数为k的集合有C^k_n个子集,那么枚举的时间复杂度为sum{c^k_n * 2^k} = 3^n