2594 解药还是毒药

题目描述 Description

Smart研制出对付各种症状的解药,可是他一个不小心,每种药都小小地配错了一点原料,所以这些药都有可能在治愈某些病症的同时又使人患上某些别的病症(你可能会问那…那是解药还是毒药啊?)……,经过Smart的努力,终于弄清了每种药的具体性能,他会把每种药能治愈的病症和能使人患上的病症列一张清单给你,然后你要根据这张清单找出能治愈所有病症的最少药剂组合……顺便说一声,病症的数目不超过10种,而且他的药是用不完的,就是说每种药剂都可以被重复使用。

输入描述 Input Description

给你们的单子里第一行是病症的总数n(1≤n≤10)。第二行是药剂的种类m(0<m≤100)。

以下有m行,每行有n个数字用空格隔开,文件的第i+2行的n个数字中,如果第j个数为1,就表示第i种药可以治愈病症j(如果患有这种病的话则治愈,没有这种病则无影响),如果为0表示无影响,如果为-1表示反而能使人得上这种病(无病患上,有病无影响)。Smart制的药任何两种性能都不同。

输出描述 Output Description

你只要输出用的最少的药剂数就可以了,其实还有可能用尽了所有的药也不能将所有病治愈,那样的话你们只要输出“The patient will be dead.”就可以了。

样例输入 Sample Input

3

2

1 0 1

-1 1 0

样例输出 Sample Output

2

数据范围及提示 Data Size & Hint

1≤n≤10

0<m≤100

本题可以转化为最短路问题

我们设第i种病没治愈为1,治愈了为0。例:二进制状态100表示第1种症状被治愈了,第2、3种症状没被治愈,转化为十进制为4。

初始状态为二进制状态下的n个1,转化为十进制为2^n-1,目标状态为0。把由初始状态到达目标状态所经历的所有状态看做一个个点,所有边的边权为1。

那么题目转化为:从状态2^n-1到状态0的最短路径。

基本算法:SPFA

解题所需自定义函数:十进制与二进制的转换

十进制转二进制:

以10为例:

10%2=0,10/2=5;

5%2=1,5/2=2;

2%2=,2/2=1;

1%2=1,1/2=0;结束

所以为1010

二进制转十进制:

以1010为例:

等于0*2^0 + 1*2^1 + 0*2^2 + 1*2^3=10

#include<cstdio>
#include<iostream>
#include<cmath>
using namespace std;
int n,m;
int head=,tail=;//我用的是左闭右开区间,即区间范围为[head,tail-1]
int l[];//二进制状态存储数组
int a[][];//a[i][j]表示第i种药剂对症状j的疗效
bool t[];//十进制判重数组
struct node
{
int w,sum;//w当前状态,十进制,sum达到状态w所需的药剂数
};
node q[];//队列
node now;
int change(int s)
{
if(!s) return ;
return l[s]+change(s-)*;
}
int work(int d,int g)//d:第d种药剂,g:使用d药剂之前的状态,十进制
{
for(int i=n;i;i--)//将十进制g转化为二进制,并一位一位的存在l数组中
{
l[i]=g%;
g/=;
}
for(int i=;i<=n;i++)//第d种药剂对状态的修改
{
if(a[d][i]==) l[i]=;
else if(a[d][i]==-) l[i]=;
}
int er=change(n);//因为l数组中的数是一位一位存的,这一句要把l[]数组中的数合起来。例:l[1]=1,l[2]=0;er=10
int k=,u=;//二进制er转为十进制k
while(er)
{
int y=er%;
k+=y*pow(,u);
u++;
er/=;
}
return k;
}
void push(node cur)
{
q[tail++]=cur;
}
void pop()
{
head++;
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=;i<=m;i++)
for(int j=;j<=n;j++)
scanf("%d",&a[i][j]);
q[tail].w=pow(,n)-;//初始状态n个1所代表的二进制数,转化为十进制为2^n-1
q[tail].sum=;//初始没用任何药剂
t[q[].w]=true;
tail++;//入队,队尾指针后移
while(head<tail)//队列不为空
{
for(int i=;i<=m;i++)//枚举每一种药剂
{
now=q[head];//取出队首
int h=work(i,now.w);//在用第i种药剂之前,状态为now.w,用了第i种药剂之后,状态为h
if(!h)//目标状态(治愈)
{
printf("%d",now.sum+);//因为now存的值是使用药剂i之前的值,而h更新是使用了药剂i之后,所以要+1
return ;
}
if(!t[h])//不是目标状态且状态h在之前没有出现过。因为spfa实质是宽搜,如果状态h在之前出现过,它在之前已经入队
{
now.sum++;//药剂数+1
now.w=h;//状态转移
push(now);//入队
t[h]=true; //状态h标记为已出现过
}
}
pop();//队首出队
}
printf("The patient will be dead.");//若队列中没有状态了,但还没有结束程序,则无药可治
}

codevs 2594 解药还是毒药的更多相关文章

  1. 解药还是毒药(codevs 2594)

    2594 解药还是毒药  时间限制: 1 s  空间限制: 128000 KB  题目等级 : 钻石 Diamond 题解  查看运行结果     题目描述 Description Smart研制出对 ...

  2. codevs2594解药还是毒药(状压dp)

    2594 解药还是毒药  时间限制: 1 s  空间限制: 128000 KB  题目等级 : 钻石 Diamond     题目描述 Description Smart研制出对付各种症状的解药,可是 ...

  3. 【BFS】【位运算】解药还是毒药

    [codevs2594]解药还是毒药 Description Smart研制出对付各种症状的解药,可是他一个不小心,每种药都小小地配错了一点原料,所以这些药都有可能在治愈某些病症的同时又使人患上某些别 ...

  4. Hash_P1026毒药?解药?

    #include <iostream> #include <cstdio> #include <algorithm> #include <cstring> ...

  5. 补丁vs错误(codevs 2218 错误答案)

    题目描述 Description 错误就是人们所说的Bug.用户在使用软件时总是希望其错误越少越好,最好是没有错误的.但是推出一个没有错误的软件几乎不可能,所以很多软件公司都在疯狂地发放补丁(有时这种 ...

  6. NOI2018准备Day12

    上午学了1个小时左右的指针,学了个从句子中分离单词的方法,其他的感觉没学到啥. 中午看了一会儿网络流,懵逼...... A了8道题,4道钻石.3道黄金.1道白银,自己写出了codevs"解药 ...

  7. java web 程序---猜数字游戏的猜了多少次的代码

    思路:用setAttribute()放 ,然后直接输出 Integer str=(Integer)session.getAttribute("count"); int num3= ...

  8. vijosP1026毒药?解药?

    hash. 怎么感觉叫状态压缩bfs比较合适呢? #include<cstdio> #include<algorithm> #include<cstring> us ...

  9. Tyvj3308毒药解药题解

    题目大意 这些药都有可能在治愈某些病症的同一时候又使人患上某些别的病症--经过我天才的努力.最终弄清了每种药的详细性能,我会把每种药能治的病症和能使人患上的病症列一张清单给你们,然后你们要依据这张清单 ...

随机推荐

  1. 深入理解和应用display属性(一)

    Display在官方定义:规定元素应该生成的框的类型.本文只重点分析常用的6个值:none.block.inline.inline-block.inherit.flex.其他table.list-it ...

  2. 精心挑选10款优秀的 jQuery 图片左右滚动插件

    在现代的网页设计中,图片和内容滑块是一种极为常见和重要的元素.你可以从头开始编写自己的滑动效果,但是这将浪费很多时间,因为网络上已经有众多的优秀的 jQuery 滑块插件.当然,如果要从大量的 jQu ...

  3. 纯CSS打造好看的按钮样式

    好看的按钮.链接.div样式,效果预览: http://hovertree.com/code/run/css/s8o19792.html 发现今天积分和排名不错: 代码如下: <!DOCTYPE ...

  4. (有趣)chrome不同浏览器版本对display:flex和溢出隐藏显示省略符号的bug

    项目中碰到一个十分有趣的情形: 布局要求是这样:右边创建新订单是固定宽度80px,左侧是自适应宽度,溢出隐藏.如下图. 这里布局不用说肯定使用display:flex的.左侧flex:1;右侧widt ...

  5. table tr foreach td 换行

    @{ ;} <table style=" class="sy_table"> <tr> @foreach (DataRow dr in (View ...

  6. AngularJS 参考手册

    AngularJS 参考手册 AngularJS 指令 本教程用到的 AngularJS 指令 : 指令 描述 ng-app 定义应用程序的根元素. ng-bind 绑定 HTML 元素到应用程序数据 ...

  7. Android开发学习——ListView+BaseAdapter的使用

    ListView 就是用来显示一行一行的条目的MVC结构 * M:model模型层,要显示的数据           ----people集合 * V:view视图层,用户看到的界面          ...

  8. UIWebView加载本地html文件

    UIWebView *webView = [[UIWebView alloc] initWithFrame:CGRectMake(, , KScreenWidth, KScreenHeight-)]; ...

  9. HADOOP安装指南-Ubuntu15.10和hadoop2.7.2

    Ubuntu15.10中安装hadoop2.7.2安装手册 太初 目录 1.      Hadoop单点模式... 2 1.1        安装步骤... 2 0.环境和版本... 2 1.在ubu ...

  10. tomcat 应用部署的几点注意

    将应用部署到Tomcat根目录的目的是可以通过"http://[ip]:[port]"直接访问应用,而不是使用"http://[ip]:[port]/[appName]& ...