题目传送门

软件补丁问题

题目描述

T 公司发现其研制的一个软件中有 n 个错误,随即为该软件发放了一批共 m 个补丁程序。每一个补丁程序都有其特定的适用环境,某个补丁只有在软件中包含某些错误而同时又不包含另一些错误时才可以使用。一个补丁在排除某些错误的同时,往往会加入另一些错误。

换句话说,对于每一个补丁 i,都有 2 个与之相应的错误集合 B1[i]和 B2[i],使得仅当软件包含 B1[i]中的所有错误,而不包含 B2[i]中的任何错误时,才可以使用补丁 i。补丁 i 将修复软件中的某些错误 F1[i],而同时加入另一些错误 F2[i]。另外,每个补丁都耗费一定的时间。

试设计一个算法,利用 T 公司提供的 m 个补丁程序将原软件修复成一个没有错误的软件,并使修复后的软件耗时最少。对于给定的 n 个错误和 m 个补丁程序,找到总耗时最少的软件修复方案。

输入输出格式

输入格式:

第 1 行有 2 个正整数 n 和 m,n 表示错误总数,m表示补丁总数,1<=n<=20, 1<=m<=100。

接下来 m 行给出了 m 个补丁的信息。每行包括一个正整数,表示运行补丁程序 i 所需时间,以及 2 个长度为 n 的字符串,中间用一个空格符隔开。

第 1 个字符串中,如果第 k 个字符 bk 为“+”,则表示第 k 个错误属于 B1[i],若为“-”,则表示第 k 个错误属于 B21[i],若为“0”,则第 k 个错误既不属于 B1[i]也不属于 B2[i],即软件中是否包含第 k 个错误并不影响补丁 i 的可用性。

第 2 个字符串中,如果第 k 个字符 bk为“-”,则表示第 k 个错误属于 F1[i],若为“+”,则表示第 k 个错误属于 F2[i],若为“0”,则第 k 个错误既不属于 F1[i]也不属于 F2[i],即软件中是否包含第 k 个错误不会因使用补丁i 而改变。

输出格式:

程序运行结束时,将总耗时数输出。如果问题无解,则输出 0。

输入输出样例

输入样例#1:

3 3
1 000 00-
1 00- 0-+
2 0-- -++
输出样例#1:

8

说明

none!


  分析:

  说好的网络流二十四题???

  反正想了很久想不到怎么搞网络流,然后一看。。。O.O???状压?SPFA?神奇。思路倒是不难,因为$n$的范围只有$20$,所以就可以用二进制来表示当前的状态,转移的时候因为需要满足包含$B1[]$中的错误,不包含$B2[]$中的错误,那么我们也可以想到把它转化成一张图,用SPFA来转移。

  一开始把输入的定义搞混调了好久,真SA。。。

  Code:

//It is made by HolseLee on 27th July 2018
//Luogu.org P2761
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<iostream>
#include<iomanip>
#include<algorithm>
#include<queue>
using namespace std; const int inf=0x3f3f3f3f;
int n,m,a[],has[],dont[],dp[(<<)],kill[],bring[];
char s[][];
bool vis[(<<)];
queue<int>t; void ready(int x)
{
for(int i=n-;i>=;--i){
switch (s[][i]){
case '+':has[x]|=(<<i);break;
case '-':dont[x]|=(<<i);break;
}
switch (s[][i]){
case '+':bring[x]|=(<<i);break;
case '-':kill[x]|=(<<i);break;
}
}
} int main()
{
scanf("%d%d",&n,&m);
for(int i=;i<=m;++i){
scanf("%d%s%s",&a[i],s[],s[]);
ready(i);
}
memset(dp,inf,sizeof(dp));
dp[(<<n)-]=;vis[(<<n)-]=true;
t.push(((<<n)-));
while(!t.empty()){
int now=t.front();t.pop();
vis[now]=false;
for(int i=;i<=m;++i){
if((has[i]&now)!=has[i])continue;
if((dont[i]&(~now))!=dont[i])continue;
int to=(now&(~kill[i]))|bring[i];
if(dp[to]<=dp[now]+a[i])continue;
dp[to]=dp[now]+a[i];
if(!vis[to]){
t.push(to);vis[to]=true;
}
}
}
if(dp[]==inf)printf("0\n");
else printf("%d\n",dp[]);
return ;
}

洛谷P2761 软件补丁问题 [状压DP,SPFA]的更多相关文章

  1. 洛谷P2761 软件补丁问题(状压DP,SPFA)

    题意 描述不清... Sol 网络流24题里面怎么会有状压dp?? 真是狗血,不过还是简单吧. 直接用$f[sta]$表示当前状态为$sta$时的最小花费 转移的时候枚举一下哪一个补丁可以搞这个状态 ...

  2. 洛谷P2761 软件补丁问题(状压dp)

    传送门 啊咧……这题不是网络流二十四题么……为啥是个状压dp…… 把每一个漏洞看成一个状态,直接硬上状压dp 然后因为有后效型,得用spfa //minamoto #include<iostre ...

  3. 【题解】洛谷P3959 [NOIP2017TG] 宝藏(状压DP+DFS)

    洛谷P3959:https://www.luogu.org/problemnew/show/P3959 前言 NOIP2017时还很弱(现在也很弱 看出来是DP 但是并不会状压DP 现在看来思路并不复 ...

  4. 洛谷 P1278 单词游戏 【状压dp】

    题目描述 Io和Ao在玩一个单词游戏. 他们轮流说出一个仅包含元音字母的单词,并且后一个单词的第一个字母必须与前一个单词的最后一个字母一致. 游戏可以从任何一个单词开始. 任何单词禁止说两遍,游戏中只 ...

  5. 洛谷P2704 [NOI2001]炮兵阵地 [状压DP]

    题目传送门 炮兵阵地 题目描述 司令部的将军们打算在N*M的网格地图上部署他们的炮兵部队.一个N*M的地图由N行M列组成,地图的每一格可能是山地(用“H” 表示),也可能是平原(用“P”表示),如下图 ...

  6. 洛谷P2831 愤怒的小鸟——贪心?状压DP

    题目:https://www.luogu.org/problemnew/show/P2831 一开始想 n^3 贪心来着: 先按 x 排个序,那么第一个不就一定要打了么? 在枚举后面某一个,和它形成一 ...

  7. 洛谷P2051 [AHOI2009] 中国象棋(状压dp)

    题目简介 n*m的棋盘,对每行放炮,要求每行每列炮数<=2,求方案数%9999973 N,M<=100 题目分析 算法考虑 考虑到N,M范围较小,每一行状态只与前面的行状态有关,考虑状压D ...

  8. 洛谷$P$3160 局部极小值 $[CQOI2012]$ 状压$dp$

    正解:状压$dp$ 解题报告: 传送门! 什么神仙题昂,,,反正我是没有想到$dp$的呢$kk$,,,还是太菜了$QAQ$ 首先看数据范围,一个4×7的方格,不难想到最多有8个局部极小值,过于显然懒得 ...

  9. 洛谷 [P2761] 软件补丁问题

    并不是网络流 状压+SPFA 通过题目中的描述及数据范围可知,我们状压当前的漏洞,以每个二进制位表示是否有这个漏洞,并以状压的结果为顶点,以补丁的时间为边跑SPFA即可 #include <io ...

随机推荐

  1. 树链剖分处理+线段树解决问题 HDU 5029

    http://acm.split.hdu.edu.cn/showproblem.php?pid=5029 题意:n个点的树,m次操作.每次操作输入L,R,V,表示在[L,R]这个区间加上V这个数字.比 ...

  2. Goolge-Guava Concurrent中的Service

    最近在学习了下Google的Guava包,发现这真是一个好东西啊..由于平时也会写一些基于多线程的东西,所以特意了解了下这个Service框架.这里Guava包里的Service接口用于封装一个服务对 ...

  3. GridControl详解(三)列数据的格式设置

    为了测试方便,我们加入新的3列,格式分别是数据,时间,字符串.代码增加下列部分: //格式增加 dt.Columns.Add("数据",typeof(decimal)); dt.C ...

  4. cmd 使用gii的命令行用法

    1.生成模型 php yii gii/model --ns=common\models --tableName=contract_supplemental --modelClass=ContractS ...

  5. SaltStack 使用笔记

    centos 7安装yum -y install epel-releaseyum clean allyum makecacheyum -y install salt-minionsed -i 's/# ...

  6. VC连接access

    (1)首先拷贝 c:\program files\common files\system\ado\ 目录中的 msado15.dll 文件到项目中. (2)在VC中加入DLL,具体方法如下: (3)创 ...

  7. python3学习笔记.1.初体验

    最近工作烦得很 就想找点儿别的事情来做,于是想到了学学python. 因为是vs2017,所以就在里面安装了. 第一个程序肯定是Hello World了. 新建一个python应用程序 代码只有一行 ...

  8. 南邮综合题writeup

    http://teamxlc.sinaapp.com/web3/b0b0ad119f425408fc3d45253137d33d/index.php fuckjs直接console得到地址 http: ...

  9. angular 最大字数限制

    js可以通过onkeyup onkeydown判断当前节点字数. angular可以通过监听的方式: $scope.input = {//初始化,避免ng-model绑定取不到值 MaxBT:'', ...

  10. 数据库与sql注入的相关知识

    数据库与sql注入的相关知识 sql语句明显是针对数据库的一种操作,既然想通过sql注入的方法来拿取数据那么就要先了解一下如何的去操作数据库,这方面并不需要对数据库有多么的精通但是如果了解掌握了其中的 ...