博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
UVA 11825 - Hackers' Crackdown 状态压缩 dp 枚举子集
阅读量:6117 次
发布时间:2019-06-21

本文共 1383 字,大约阅读时间需要 4 分钟。

UVA 11825 - Hackers' Crackdown 状态压缩 dp 枚举子集

ACM

题目地址:

题意: 

有一个由编号0~n-1的n台计算机组成的网络,一共同拥有n种服务,每台计算机上都执行着所有服务,对于每台计算机,你能够选择停止一项服务,这个行为会导致与这台计算机和与他相连的其它计算机上的这项服务都停止(原来已经停止的继续保持停止状态)。

求最多能使多少个服务瘫痪(即没有不论什么一台计算机在执行这项服务)。

分析: 

题目说白了。就是: 
把n个集合p[i],0<=i<n分成尽量多组,使得每组中各个集合的并集为全集。 
利用状态压缩。记录每一个节点执行的服务。因为数据大小就16所以直接能够用int范围数字表示一个集合。 
然后预处理下cover,处理16个节点组成的各个集合会带来的挺服务效果。 
然后dp,假设cover[S0] == all (all全为1) 那么是S^S0 的部分也有可能终止服务 。dp[S] = max(dp[S], dp[S^S0]+1)

參考了,嘛。是为了了解枚举子集做的题目。

枚举子集的模板:

 
  1. // 对于集合S
  2. for (int S0 = S; S0; S0 = S&(S0 - 1)) // 枚举S0为子集
  3. ...

原理:S&(S0 - 1) 实际上是把S中的0所有忽略。并不断减1的结果。

代码

/**  Author:      illuz 
* File: 11825.cpp* Create Date: 2014-06-27 20:43:48* Descripton: sub set/ dp/ numeric */#include
#include
#include
using namespace std;const int N = 16;int n, m, t, mask[N], cover[1<
<< i); while (m--) { scanf("%d", &t); mask[i] |= (1 << t); } } // get the union set of cover for (int S = 0; S < (1 << n); S++) { cover[S] = 0; for (int i = 0; i < n; i++) { if (S & (1 << i)) { cover[S] |= mask[i]; } } } // dp dp[0] = 0; tot = (1 << n) - 1; for (int S = 1; S < (1 << n); S++) { dp[S] = 0; for (int S0 = S; S0; S0 = (S0 - 1)&S) { if (cover[S0] == tot) { dp[S] = max(dp[S], dp[S^S0] + 1); } } } printf("Case %d: %d\n", ++cas, dp[tot]); } return 0;}

转载地址:http://yuvka.baihongyu.com/

你可能感兴趣的文章
HDU 2818 (矢量并查集)
查看>>
【转】php字符串加密解密
查看>>
22. linux 常用命令
查看>>
ASP.Net 使用GridView模板删除一行的用法
查看>>
(十六)字段表集合
查看>>
JPGraph
查看>>
实验二 Java面向对象程序设计
查看>>
------__________________________9余数定理-__________ 1163______________
查看>>
webapp返回上一页 处理
查看>>
新安装的WAMP中phpmyadmin的密码问题
查看>>
20172303 2017-2018-2 《程序设计与数据结构》第5周学习总结
查看>>
eclipse中将一个项目作为library导入另一个项目中
查看>>
Go语言学习(五)----- 数组
查看>>
Android源码学习之观察者模式应用
查看>>
Content Provider的权限
查看>>
416. Partition Equal Subset Sum
查看>>
centos7.0 64位系统安装 nginx
查看>>
数据库运维平台~自动化上线审核需求
查看>>
注解开发
查看>>
如何用 Robotframework 来编写优秀的测试用例
查看>>