uva 11825 Hackers' Crackdown (状压dp,子集枚举)

题目链接:uva 11825

题意:

你是一个黑客,侵入了n台计算机(每台计算机有同样的n种服务),对每台计算机,你能够选择终止一项服务,则他与其相邻的这项服务都终止。你的目标是让很多其它的服务瘫痪(没有计算机有该项服务)。

思路:(见大白70页,我的方程与大白不同)

把n个集合P1、P2、Pn分成尽量多的组,使得每组中全部集合的并集等于全集,这里的集合Pi是计算机i及其相邻计算机的集合,用cover[i]表示若干Pi的集合S中全部集合的并集,dp[s]表示子集s最多能够分成多少组,则

假设cover[s]=all,那么dp[s]至少为1.

dp[s]=max(dp[s],dp[s0]+dp[s^s0]);  (两个子集的和)

代码:

#include <cstdio>
#include <cstring>
#include <algorithm>
#define N 16
using namespace std;

int n, m, x, dp[1<<N], cover[1<<N], p[N];

int main ()
{
    int k = 0;
    while(scanf("%d",&n), n)
    {
        for(int i = 0; i < n; i++)
        {
            p[i] = 1<<i;
            scanf("%d",&m);
            for(int j = 0; j < m; j++)
            {
                scanf("%d",&x);
                p[i] |= 1<<x;
            }
        }
        for(int s = 0; s < (1<<n); s++)
        {
            cover[s] = 0;
            for(int i = 0; i < n; i++) if(s&1<<i)
            cover[s] |= p[i];
        }
        dp[0] = 0;
        int all = (1<<n)-1;
        for(int s = 1; s < (1<<n); s++)
        {
            if(cover[s]!=all) dp[s] = 0;
            else dp[s]=1;
            for(int s0 = s; s0; s0 = (s0-1)&s)  // 枚举子集的技巧 s0为s除空集之外的全部子集
            {
                dp[s] = max(dp[s], dp[s^s0]+dp[s0]);
            }
        }
        printf("Case %d: %d\n",++k, dp[all]);
    }
    return 0;
}
/*
3
2 1 2
2 0 2
2 0 1

5
2 0 1
2 0 2
2 0 1
1 4
1 3

4
2 1 2
3 0 2 3
3 0 1 3
2 1 2
*/

uva 11825 Hackers' Crackdown (状压dp,子集枚举),布布扣,bubuko.com

uva 11825 Hackers' Crackdown (状压dp,子集枚举)

时间: 2024-10-17 01:35:12

uva 11825 Hackers&#39; Crackdown (状压dp,子集枚举)的相关文章

UVA 11825 Hackers&#39; Crackdown 状压DP

感觉白书上的做法很神! 首先状压表示电脑之间的联通关系,然后预处理出所有关闭电脑的组合达到的状态,然后枚举每个状态并且枚举每个状态的所有子集,之后无脑递推就木有了. 关于枚举一个状态所有子集的小技巧:假设当前状态是S0 有 for s = s0; s != 0; s =  (s - 1) & s0 #include <cstdio> #include <cstring> #include <iostream> #include <map> #incl

UVA 11825 Hackers’ Crackdown 状压DP枚举子集势

Hackers’ Crackdown 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 with each of them running a set of Nservices. Note

uva 11825 Hackers&#39; Crackdown (状压dp,子集枚举)

题目链接:uva 11825 题意: 你是一个黑客,侵入了n台计算机(每台计算机有相同的n种服务),对每台计算机,你可以选择终止一项服务,则他与其相邻的这项服务都终止.你的目标是让更多的服务瘫痪(没有计算机有该项服务). 思路:(见大白70页,我的方程与大白不同) 把n个集合P1.P2.Pn分成尽量多的组,使得每组中所有集合的并集等于全集,这里的集合Pi是计算机i及其相邻计算机的集合,用cover[i]表示若干Pi的集合S中所有集合的并集,dp[s]表示子集s最多可以分成多少组,则 如果cove

状压DP [Uva 11825] Hackers’ Crackdown

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 w

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

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

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

题解: 首先将相邻点进行二进制,保存在p[i]中 然后将不同组合的p[i]组合的值记录下来,保存在cover[i]中 然后从小到大进行dp s0为集合s的子集 if(cover[ s0 ] == all - 1) f[s] = max( f[s], f[s ^ s0] + 1); 代码: #include<bits/stdc++.h> using namespace std; #define pb push_back #define mp make_pair #define se second

UVA - 11825 —— Hackers&#39; Crackdown

题目:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=18913 这道题是一道状态压缩DP的好题,有几点要注意的: 1.uva给出的题目不知道为何,题意是有些描述不清的,详见<训练指南> 2.这道题可以有很多写法,整个的dp求解和cover那个部分既可以写成记忆化搜索自顶向下,也可以自底向上来实现. #include <cstdio> #include <iostream> #include <

UVA 11691 - Allergy Test(状压dp+贪心)

题目链接:11691 - Allergy Test 题意:这题题意看了老半天都没弄懂,好在后面找到个PPT,上面有中文题意- -,不过上面的做法是纯贪心,挺巧妙的但是感觉有点不靠谱, 下载地址:http://par.cse.nsysu.edu.tw/~advprog/advprog2011/11691.ppt 給N種過敏原的存活期,每天可把一種過敏原注入人體內.若有兩個以上過敏原存活於人體中,則無法進行實驗(也就是每種過敏原都必須有一天是單獨存活於人體中).實驗結束於最後的過敏原死亡的那天,求最