这是我做状压DP的第一道题,状压里面都是用位运算来完成的,只要耐下心来弄明白每次位运算的含义,还是容易理解的。

题意:

有编号为0~n-1的n台服务器,每台都运行着n中服务,每台服务器还和若干台其他服务器相连。对于每台服务器,你可以选择停止该台以及与这台服务器相连的服务器的一项服务。如果一台服务器的所有服务都被停止,则这台服务器瘫痪。问最多能使多少台服务器瘫痪

转化为数学模型(题目是如何抽象成这种数学模型的也要好好想想):

把n个集合尽可能多的分成若干组,使得每组所有集合的并集为全集。这里集合Pi表示服务器i以及与其相邻服务器的集合

算法:

数组P[i]表示服务器i以及与其相邻服务器的集合的二进制表示

枚举所有集合可能的组合情况,一共有2n种,计算其并集保存在cover中

f[S]表示子集S最多可以分成多少组

状态转移方程:

枚举S的子集S0

f[S] = max{f[S], f[S - S0] + 1 | 这里S0是S子集而且cover[S0]为全集}

这里再说一下枚举S0用代码实现的技巧:

在二进制中S0的1的个数肯定比S要少,所以从数值大小上来看S0 < S

我们先令S0 = S - 1

那么 S & (S0 - 1)就是S的子集了

因为上面的表达式满足两个条件:

  1. S0 < S
  2. S0的1的个数比S要少

S ^ S0的含义:

S ^ S0代表以S为全集S0的补集,为什么用异或运算实现呢?自己动手模拟一下就清楚了,嘿嘿

好了,写到这里,这道题就分析的很透彻了。看来位运算还是蛮有意思的

 //#define LOCAL
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std; const int maxn = ( << ) + ;
int cover[maxn], p[], f[maxn]; int main(void)
{
#ifdef LOCAL
freopen("11825in.txt", "r", stdin);
#endif int n, kase = ;
while(scanf("%d", &n) == && n)
{
memset(f, , sizeof(f));
for(int i = ; i < n; ++i)
{
int m, x;
scanf("%d", &m);
p[i] = ( << i);
while(m--)
{
scanf("%d", &x);
p[i] |= ( << x);
}
} for(int i = ; i < ( << n); ++i)
{
cover[i] = ;
for(int j = ; j < n; ++j)
{
if(i & ( << j))
cover[i] |= p[j];
}
} f[] = ;
int all = ( << n) - ;
for(int s = ; s < ( << n); ++s)
{
f[s] = ;
for(int s0 = s; s0; s0 = (s0 - ) & s)
if(cover[s0] == all)
f[s] = max(f[s], f[s0 ^ s] + );
} printf("Case %d: %d\n", ++kase, f[all]);
}
return ;
}

代码君

UVa 11825 (状压DP) Hackers' Crackdown的更多相关文章

  1. Hackers' Crackdown( UVA UVA 11825状压dp)

    题意:N台电脑,现在有N种服务,现在你可以在每台电脑终止一项服务,他和他相邻的电脑都会被关闭,如果一项服务在所有电脑都没运行,该项服务成功被破坏,问最多能破坏几种服务. 分析:把n个集合分成尽量多组, ...

  2. UVA - 11825 状压DP

    该题目是EMAXX推荐的练习题,刘汝佳的书也有解说 如果S0属于全集,那S0就可以作为一个分组,那么S分组数可以是best{当前S中S0的补集+1} 对于集合类的题目我觉得有点抽象,希望多做多理解把 ...

  3. UVA - 10817 状压DP

    题意:大白P95 本题比较特别的是状压两个集合并且进行转移,因此要分别处理当前集合只有1个老师/2个老师的记录(然后可O(1)得出0个老师的集合) 记忆化过了但是迭代式不能记忆超过2的之前的状态是怎样 ...

  4. UVa 1252 (状压DP + 记忆化搜索) Twenty Questions

    题意: 有n个长为m的各不相同的二进制数(允许存在前导0),别人已经事先想好n个数中的一个数W,你要猜出这个数. 每次只可以询问该数的第K为是否为1. 问采用最优询问策略,则最少需要询问多少次能保证猜 ...

  5. UVa 10817 (状压DP + 记忆化搜索) Headmaster's Headache

    题意: 一共有s(s ≤ 8)门课程,有m个在职教师,n个求职教师. 每个教师有各自的工资要求,还有他能教授的课程,可以是一门或者多门. 要求在职教师不能辞退,问如何录用应聘者,才能使得每门课只少有两 ...

  6. UVA - 11795 状压DP

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

  7. UVa 11795 状压DP Mega Man's Mission

    kill[S]表示消灭机器人的集合为S,剩下的所能杀死的机器人集合. 设d(S)表示杀死机器人集合为S的方法数,答案为d((1<<n) - 1). d(S)可以由d(S')转移过来,其中S ...

  8. UVa 12235 状压DP Help Bubu

    题解戳这 一开始没看懂题解,后来想明白以后,d(i, j, s, x)是考虑第i本书的时候,前面已经拿走了j本书,剩下的书的种类的二进制状态为s,剩下的最后一本书的编号为x,所能得到的最小混乱度. 这 ...

  9. UVa 11825 Hackers' Crackdown (状压DP)

    题意:给定 n 个计算机的一个关系图,你可以停止每台计算机的一项服务,并且和该计算机相邻的计算机也会终止,问你最多能终止多少服务. 析:这个题意思就是说把 n 台计算机尽可能多的分成一些组,使得每组的 ...

随机推荐

  1. 创建本地yum源及grouplist 出错

    RHEL有时候使用自定义的YUM源是很方便的事情. yum install createrepo createrepo /your/repo/directory/ 不过由于粗心,本人在使用时遇到很郁闷 ...

  2. 提高Python运行效率的六个窍门

    曾灵敏 - MAY 18, 2015 Python是一门优秀的语言,它能让你在短时间内通过极少量代码就能完成许多操作.不仅如此,它还轻松支持多任务处理,比如多进程. 不喜欢Python的人经常会吐嘈P ...

  3. POJ 2513 Colored Sticks (离散化+并查集+欧拉通路)

    下面两个写得很清楚了,就不在赘述. http://blog.sina.com.cn/s/blog_5cd4cccf0100apd1.htmlhttp://www.cnblogs.com/lyy2890 ...

  4. TCP套接字编程

    一.套接字(socket)函数 图1给出了在一个TCP客户与服务器通信的流程.服务器首先启动,稍后某个客户启动,它试图连接到服务器.假设客户给服务器发送一个请求,服务器处理该请求,并且给客户发回一个相 ...

  5. (转)Android学习进阶路线导航线路(Android源码分享)

     转载请注明出处:http://blog.csdn.net/qinjuning 前言:公司最近来了很多应届实习生,看着他们充满信心但略带稚气的脸庞上,想到了去年的自己,那是的我是不是也和 现在的他们一 ...

  6. MongoDB (一) MongoDB 介绍

    MongoDB 是一个跨平台的,面向文档的数据库,提供高性能,高可用性和可扩展性方便. MongoDB工作在收集和文件的概念. 数据库 数据库是一个物理容器集合.每个数据库都有自己的一套文件系统上的文 ...

  7. lintcode:寻找旋转排序数组中的最小值 II

    寻找旋转排序数组中的最小值 II 假设一个旋转排序的数组其起始位置是未知的(比如0 1 2 4 5 6 7 可能变成是4 5 6 7 0 1 2). 你需要找到其中最小的元素. 数组中可能存在重复的元 ...

  8. java连接access数据库

    完整代码: package odbcj; import java.sql.Connection; import java.sql.DriverManager; import java.sql.Prep ...

  9. 查看服务器硬件配置信息(cpu/内存)

    1.查看cpu情况: 方法一:   Linux下CPU相关的参数保存在 /proc/cpuinfo 文件里   cat /proc/cpuinfo |more   方法二:   采用命令 dmesg ...

  10. 怎样查看Tomcat动态控制台信息

    在web项目调试期间,时常需要查看输出的调试信息,例如当hibernate设置为显示SQL语句时,每次运行的SQL语句会输出到终端,另外有时需要在代码中插入一些输出语句,以方便掌握运行情况,但当插入S ...