P2761 软件补丁问题

文章目录

    • 题目描述
    • 题解:
    • 代码:

添加链接描述

题目描述

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。

输入输出样例
输入

3 3
1 000 00-
1 00- 0-+
2 0-- -++

输出

8

题解:

样例分析:
圆圈表示还没修复,三角表示已修复
按照题目所给要求以及样例读入,我们可以得到以下分析
所采用的补丁分别为补丁1,2,1,3,1,2,1.
然后错误全部修复,总耗时为8
在这里插入图片描述
思路:
我是在刷网络流24题遇到的,看完后怎么想也想不到网络流。。。
感觉dp或者是最短路?
看了题解还真是,妙啊 ~ ~ (啥玩意还带这么坑人的)
还真是网络流24题中没网络流,老婆饼里没老婆
借用一张照片
在这里插入图片描述
第一步: 怎么和最短路联系到一起?
最短路无疑就是起点,终点,中间点,还有各点之间的线段
前三种点都是节点,在本题中节点就是错误修复的状态,起点就是全没修复,终点就是全修复了,每次修复一些错误或者新添一些错误,此时的修复状态就是当前状态。线段长度就是运行补丁的时间。我们在输入每一个补丁的时候,可以枚举一种状态,如果当前状态可以使用补丁,就算出使用补丁后的状态,前状态连一条边到后状态,长度也就是补丁时长
第二步: 状态压缩
n<=20,也就是最多20个错误,而每个错误只有修好和没修好俩状态,我们可以用01来表示(1表示没修好,0表示修好),这样20个错误其实就是一个01串,
比如bug3已经修好,1和2还未修好,那01串就是110,转化成十进制就是6。而初始状态(都未修好)为111,对应7。结束状态是都修好了为000,对应0。当有n个错误时,初始状态就是n个1,十进制也就是2n-1,即(1<<n)-1。结束就是0
第三步: 状态转移
补丁使用是有严格要求的,有些位置为1,有些位置为0,才能使用
题目中有b1,b2,f1,f2
软件包含b1错误,不包含b2错误,能够修复f1,加入错误f2
我们看看补丁3

0-- -++

使用状态:(判断一个补丁包能否使用)
b1是000=0(因为第一个字符串里面没有+)
b2是011=3(第一个字符串中 第二三位是-)
记当前状态为x
1.判断x中b1位上是否都为1(说明x是否含有b1错误)
我们可以将x与b1按位与。如果得到的值是b1本身,那就说明x的b1位上都是1
2.判断x中b2位上是否都为0(说明x是否含有b2错误)
也是将b2与x按位与,如果得到的都是0,说明x的b2位上都是0

if((x&p[i].b1)==p[i].b1 && (x&p[i].b2)==0)//说明该补丁包可以使用

修复状态:(使用后的情况)
使用后,f1位置会修好变成0,f2会变成1。
当前状态为x,如果要将f2位置变成1,直接x或上f2即可。f1位置变成0,我们可以或上一个f1,使得当前状态的所有f1位置都变成1,再异或一个f1,这样就可以将f1所有位置变成0.

int y=((x|p[i].f1)|p[i].f2)^p[i].f1;

应该算讲的很详细了吧!

代码:

//第一个字符串中+ 
//第二个字符串-
#include<bits/stdc++.h>
#define Maxn 100
#define Maxm 100
#define Maxnum  4000000using namespace std;inline int read(){char c=getchar();int x=0,f=1;while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}return x*f;
}int n,m; 
int ST;struct debug{int b1;int b2;int f1;int f2;int T;
}hero[Maxm+2];priority_queue < pair<int,int> > q;
int dist[Maxnum]; 
int vis[Maxnum];
void dj(){memset(dist,0x3f,sizeof(dist));dist[ST]=0;q.push(make_pair(0,ST));while(!q.empty()){int now=q.top().second;q.pop();if(vis[now]==1) continue;vis[now]=1;for(int i=1;i<=m;i++){if( (hero[i].b1&now)==hero[i].b1 && (hero[i].b2&now)==0 ){int v=((now|hero[i].f1)^hero[i].f1)|hero[i].f2;if(dist[now]+hero[i].T<dist[v]){dist[v]=dist[now]+hero[i].T;q.push(make_pair(-dist[v],v));}}}}
}int main(){n=read(); m=read();for(int i=1;i<=n;i++)ST=ST|(1<<i);//ST表 cout<<ST<<endl;for(int i=1;i<=m;i++){hero[i].T=read();string B,F;cin>>B>>F;for(int j=0;j<=n-1;j++){if(B[j]=='+')hero[i].b1=hero[i].b1|(1<<(j+1));if(B[j]=='-')hero[i].b2=hero[i].b2|(1<<(j+1));if(F[j]=='+')hero[i].f2=hero[i].f2|(1<<(j+1));if(F[j]=='-')hero[i].f1=hero[i].f1|(1<<(j+1));}}dj();if(dist[0]==dist[Maxnum-1])cout<<"0";elsecout<<dist[0];return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/319948.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

P4091-[HEOI2016/TJOI2016]求和【斯特林数,NTT】

正题 题目链接:https://www.luogu.com.cn/problem/P4091 题目大意 给出nnn&#xff0c;求 ∑i0n∑j0i{ij}2jj!\sum_{i0}^n\sum_{j0}^i\begin{Bmatrix}i\\j\end{Bmatrix}2^jj!i0∑n​j0∑i​{ij​}2jj! 解题思路 看题解才知道2jj!2^jj!2jj!对这nlog⁡nn\log nnlogn做法没有任…

Xamarin中国技术社区及BXUG官网上线啦

Xamarin中国技术社区及BXUG官网为.NET开发者提供移动跨平台技术学习的园地&#xff0c;为Xamarin及.NET技术达人提供展示分享的舞台&#xff0c; 为企业CTO等技术负责人提供跨平台移动应用解决方案的交流平台&#xff01;网址链接&#xff1a;http://bxug.bopoda.cn/Xamarin中国…

MST(最小生成树)的构造

是什么&#xff1a; 一个有 n 个结点的连通图的生成树是原图的极小连通子图&#xff0c;且包含原图中的所有 n 个结点&#xff0c;并且有保持图连通的最少的边。 kruskal算法&#xff1a; #include<iostream> #include<vector> #include<algorithm> #incl…

【虚树】世界树(金牌导航 虚树-1/luogu 3233)

世界树 金牌导航 虚树-1 luogu 3233 题目大意 对于一棵树&#xff0c;给出若干询问&#xff0c;每个询问告诉你若干个特殊点&#xff0c;对于所有点&#xff0c;都会选择离自己最近&#xff08;距离相等就选编号最小的&#xff09;的特殊点&#xff0c;问对于所有特殊点&am…

用python将图片转换成二值图像

大创项目是图像识别&#xff0c;第一个任务是将一个图片转换成二值图像 之前用过python的numpy和turtle&#xff0c;这次要用到图像库PIL的类Image&#xff0c;也算是刚刚从零开始学起 整体效果&#xff08;用01串表示图像&#xff09; 原理很简单&#xff1a;将图片中黑色…

.Net Core SignalR 初体验

前言Asp.Net SignalR已经出来很久了&#xff0c;但是一直没有静下心来好好看看。昨天花了几个小时的时间看了下。首先借鉴了官方文档&#xff0c;如何搭建一个SignalR的Demo。参考文章&#xff1a;https://docs.microsoft.com/zh-cn/aspnet/core/tutorials/signalr?viewaspnet…

CF1251F-Red-White Fence【NTT】

前言 刚开始看错题推了半天的生成函数 正题 题目链接:https://www.luogu.com.cn/problem/CF1251F 题目大意 nnn个白色木板&#xff0c;kkk个红色木板&#xff0c;给出这些木板的高度&#xff0c;木板排成一排形成栅栏。栅栏要求只有一个红色木板且在红色木板左边单调升&…

图论复习——dfs树,点双,边双,强连通分量

知识点 dfs树 对一个图运行 dfs 算法&#xff0c;每个点uuu的父亲定义为第一次遍历uuu时的前驱结点&#xff0c;若无则为根。 无向图的 dfs树 没有横叉边。 有向图的 dfs树 横叉边方向唯一&#xff0c;总是从后访问的点指向先访问的点。 dfs树详解 tarjan 点双 定义&#…

Android 网络状态判断

1、获取网络信息&#xff0c;首先需要获取权限 <uses-permission android:name"android.permission.INTERNET" /> <uses-permission android:name"android.permission.ACCESS_NETWORK_STATE" /> 2.1我们通过ConnectivityManager可以获取状态…

【点分治】Tree(luogu 4178/金牌导航 点分治-1)

Tree luogu 4178 金牌导航 点分治-1 题目大意 给出一棵树&#xff0c;问你书中路径长度小于等于k的点对个数有多少个 输入样例 5 1 2 3 1 3 1 1 4 2 3 5 1 4输出样例 8数据范围 1⩽N⩽41041\leqslant N \leqslant 4\times 10^41⩽N⩽4104 解题思路 对于该树&#xff0…

均分纸牌问题

均分纸牌有三种情况&#xff1a;线性&#xff0c;环形&#xff0c;二维 文章目录线性题目描述思路&#xff1a;代码&#xff1a;环形题目描述思路代码线性 题目描述 P1031 均分纸牌 有N堆纸牌&#xff0c;编号分别为1,2,…,N。每堆上有若干张&#xff0c;但纸牌总数必为N的倍…

.net core实践系列之短信服务-Api的SDK的实现与测试

前言上一篇《.net core实践系列之短信服务-Sikiro.SMS.Api服务的实现》讲解了API的设计与实现&#xff0c;本篇主要讲解编写接口的SDK编写还有API的测试。或许有些人会认为&#xff0c;SDK的编写可以不需要&#xff0c;既然已经用了RESTful web服务与Swagger提供的接口描述&…

[集训队作业2018] count(笛卡尔树,生成函数,卡特兰数)

传送门 什么情况下两序列同构 对于两序列A[1,n],B[1,n]A[1,n],B[1,n]A[1,n],B[1,n]&#xff0c;设fA(1,n)pa,fB(1,n)pbf_A(1,n)p_a,f_B(1,n)p_bfA​(1,n)pa​,fB​(1,n)pb​&#xff0c; 若pa̸pbp_a\notp_bpa​​pb​&#xff0c;A,BA,BA,B一定不同构。若papbp_ap_bpa​p…

【启发式合并】梦幻布丁(金牌导航 启发式合并-1/luogu 3201)

梦幻布丁 金牌导航 启发式合并-1 luogu 3201 题目大意 有若干个布丁&#xff0c;给出它们的颜色&#xff0c;每次将一个颜色的所有布丁变成另一种颜色&#xff0c;然后询问有多少段连续的数 输入样例 4 3 1 2 2 1 2 1 2 1 2输出样例 3 1样例解释 初始时布丁颜色依次为 …

P4717-[模板]快速莫比乌斯/沃尔什变换(FMT/FWT)

正题 题目链接:https://www.luogu.com.cn/problem/P4717 题目大意 给出两个长度为2n2^n2n的数列A,BA,BA,B求 Cn∑iorjnAiBjC_{n}\sum_{i\ or\ jn}A_iB_jCn​i or jn∑​Ai​Bj​ Cn∑iandjnAiBjC_{n}\sum_{i\ and\ jn}A_iB_jCn​i and jn∑​Ai​Bj​ Cn∑ixorjnAiBjC_{n}\su…

P4016 负载平衡问题

文章目录题目描述题解&#xff1a;方法一&#xff1a;代码&#xff1a;方法二&#xff1a;P4016 负载平衡问题题目描述 G 公司有 n 个沿铁路运输线环形排列的仓库&#xff0c;每个仓库存储的货物数量不等。如何用最少搬运量可以使 n 个仓库的库存数量相同。搬运货物时&#xff…

Ocelot简易教程(二)之快速开始2

为什么这篇的标题叫“Ocelot简易教程&#xff08;二&#xff09;之快速开始2”呢&#xff0c;因为很多朋友跟我说上一篇“ Ocelot简易教程&#xff08;二&#xff09;之快速开始1”内容太少了&#xff0c;只是简单介绍Ocelot的一些简单配置&#xff0c;让Ocelot能跑起来&#x…

【线性基】彩灯(luogu 3857/金牌导航 线性基-1)

彩灯 luogu 3857 金牌导航 线性基-1 题目大意 给若干个01串&#xff0c;让你选择其中一些&#xff0c;问你异或的值有多少种 输入样例 2 3 OO XO OX输出样例 4数据范围 1⩽N,M⩽501\leqslant N,M\leqslant 501⩽N,M⩽50 解题思路 对于原来的01串&#xff0c;先求出其线…

[POI2015] Pustynia(差分约数,线段树优化建图,拓扑)

传送门 Description 给定一个长度为n的正整数序列aaa&#xff0c;每个数都在111到10910^9109范围内&#xff0c;告诉你其中sss个数&#xff0c;并给出mmm条信息&#xff0c;每条信息包含三个数l,r,kl,r,kl,r,k以及接下来kkk个正整数x1,x2,...,xkx_1,x_2,...,x_kx1​,x2​,...…

CF662C-Binary Table【FWT】

正题 题目链接:https://www.luogu.com.cn/problem/CF662C 题目大意 n∗mn*mn∗m的网格上有0/10/10/1&#xff0c;可以任意翻转行和列&#xff0c;求剩下最少的111。 解题思路 知道是FWTFWTFWT之后就好做很多了。 首先因为nnn很小&#xff0c;所以可以考虑枚举翻转的行数&…