题解报告——程序补丁

程序补丁(bugs)

时间限制: 1000 ms         内存限制: 65536 KB

【题目描述】

一个程序总有个错误,公司经常发布补丁来修正这些错误,遗憾的是,每用一个补丁,在修正某些错误的时候,同时会加入某些错误,每个补丁都有一定运行时间。

某公司发表了一个游戏,出现了n个错误B={b1,b2,b3,……bn},于是该公司发布了m个补丁,每个补丁的应用都是有条件的(即哪些错误必须存在,哪些错误不能存在)。

求最少需要多少时间可全部修正这些错误。

【输入】

输入文件第一行有两个正整数n和m,n表示错误总数,m表示补丁总数,1≤n≤20,1≤m≤100。接下来m行给出了m个补丁的信息。每行包括一个正整数(表示此补丁程序的运行时间)和两个字符串,

第一个字符串描述了应用该补丁的条件。字符串的第i个字符,如果是‘+’,表示在软件中必须存在第bi号错误;如果是‘-’,表示软件中错误bi不能存在;如果是‘0’,则表示错误bi存在或不存在均可(即对应用该补丁没用影响)。

第二个字符串描述了应用该补丁的效果。字符串的第i个,如果是‘+’,表示产生了一个新错误bi;如果是‘-’,表示错误bi被修改好了;如果是‘0’,则表示错误bi不变(即原来存在的,仍然存在;原来不存在,还是不存在)。

【输出】

输出一个整数,如果问题有解,输出总耗时。否则输出-1。

【输入样例】

3 5
1 0-+ -+-
3 +-- -00
4 000 00-
6 +0+ -0-
3 0+0 0-0

【输出样例】

7

【思路分析】

这道题首先就会想到是状态压缩,但由于是求最短用时所以我们不用动规,改写spfa。

首先将每种状态记录在一个节点中,每次扩展更新从起点到每个节点的最短路(只要可以从一个状态到另一个状态就可以更新)

这道题其实非常考验位运算,是一道练习位运算的很好的题,具体位运算的精髓还是在代码里去领悟吧!!!

 

【代码实现】

 

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<queue>
 4 #include<iostream>
 5 using namespace std;
 6 queue<int> que;
 7 const int MAXN=(1<<20)+7;
 8 int b1[105],b2[105],f1[105],f2[105],t1[105],n,m;
 9 int dis[MAXN];
10 bool vis[MAXN];
11 void spfa()
12 {
13     memset(vis,false,sizeof(vis));
14     memset(dis,0x3f3f3f3f,sizeof(dis));
15     int s=(1<<n);s--;
16     que.push(s);
17     vis[s]=true;
18     dis[s]=0;
19     while(!que.empty())
20     {
21         int now=que.front();
22         que.pop();
23         vis[now]=false;
24         for(int i=1;i<=m;i++)
25         {
26             if(((b1[i]&now)==b1[i])&&((b2[i]&now)==0))
27             {
28                 int son;
29                 son=(now|f2[i]);
30                 son=(son&(~f1[i]));
31                 if(dis[son]>dis[now]+t1[i])
32                 {
33                     dis[son]=dis[now]+t1[i];
34                     if(!vis[son])
35                     {
36                         que.push(son);
37                         vis[son]=true;
38                     }
39                 }
40             }
41         }
42     }
43 }
44 int main()
45 {
46     scanf("%d%d",&n,&m);
47     for(int i=1;i<=m;i++)
48     {
49         char bb[20],ff[20];
50         int tt;
51         cin>>tt;
52         cin>>bb>>ff;
53         t1[i]=tt;
54         for(int j=0;j<n;j++)
55         {
56             if(bb[j]=='+') b1[i]=b1[i]|(1<<j);
57             if(bb[j]=='-') b2[i]=b2[i]|(1<<j);
58             if(ff[j]=='-') f1[i]=f1[i]|(1<<j);
59             if(ff[j]=='+') f2[i]=f2[i]|(1<<j);
60          }
61     }
62     spfa();
63     if(dis[0]==0x3f3f3f3f) printf("-1");
64     else printf("%d",dis[0]);
65     return 0;
66 }

 

posted @ 2018-03-27 17:14  genius777  阅读(188)  评论(0编辑  收藏  举报