UVA 11825 Hackers' Crackdown - 状压dp
2016-03-20 11:44
344 查看
题目描述
求:最多可以让多少种服务完全终止运行。
原问题<=> 将N台电脑分为一些组,满足每个组的电脑能影响的并集等于全集。求最大的组数。
dp[S]=max{dp[S],dp[s^s0]+1} (s0满足其包含的电脑能影响的并集等于全集)
(参考了网上代码)
题目大意:
N台计算机连成网络,每台计算机上都同时运行着N种服务。对于每台计算机,可以选择仅一项服务,终止这台计算机和所有与它相邻计算机的该项服务。求:最多可以让多少种服务完全终止运行。
分析:
每台电脑能影响的范围都是一定的,跟它是什么服务没关系。原问题<=> 将N台电脑分为一些组,满足每个组的电脑能影响的并集等于全集。求最大的组数。
dp[S]=max{dp[S],dp[s^s0]+1} (s0满足其包含的电脑能影响的并集等于全集)
(参考了网上代码)
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; #define MAXN 16 #define MAXST 65536 int n,p[MAXN+10],c[MAXST+10],dp[MAXST+10],S; void read() { int x,m; memset(p,0,sizeof p); for(int i=0;i<n;i++){ scanf("%d",&m); p[i]=(1<<i); for(int j=1;j<=m;j++){ scanf("%d",&x); p[i]|=(1<<x); } } memset(c,0,sizeof c); S=(1<<n)-1; for(int s=0;s<=S;s++){ for(int i=0;i<n;i++) if(s&(1<<i)) c[s]|=p[i]; } } void DP() { memset(dp,0,sizeof dp); for(int s=0;s<=S;s++){ for(int s0=s;s0;s0=(s0-1)&s){ if(c[s0]==S) dp[s]=max(dp[s],dp[s^s0]+1); } } } int main() { int cas=0; while(scanf("%d",&n)&&n){ read(); DP(); printf("Case %d: %d\n",++cas,dp[S]); } return 0; }
相关文章推荐
- PB中取得数据窗口所有列名以及列标题名称
- Activity中finish() onDestroy() 和System.exit()的区别
- 学习笔记 第四周 第一篇
- 多线程与双端队列结合使用,实现持久化任务(2)
- 最大子列和问题
- Kafka学习之三 Kafka线上环境集群部署及客户端应用
- 巧用Windows自带portproxy远程直接连接linux虚拟机
- vbs : 将WPS表格另存为文本文件
- PB数据窗口导出excel,修改第一行英文标题为中文标题,计算合计值
- android开发系列之socket编程
- 解决:Unable to execute dex: Multiple dex files define Landroid/annotation/AnimRes
- 剑指offer:和为S的连续正数序列
- SASS组件开发
- 都要学C
- 谈谈烦人的hasLayout和BFC
- 关闭SLinux
- UVA 10655 Contemplation! Algebra(构造矩阵和快速幂)
- 转载一篇对C语言中可变参数的文章
- 多线程“基础篇”01之 基本概念
- 【160312 18:00】四则运算 2