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. GJM :动作手游实时PVP 帧同步(客户端)[转载]

    原帖地址:http://gad.qq.com/article/detail/7171195 原文作者:唐声福  原帖备注:版权所有,禁止匿名转载:禁止商业使用:禁止个人使用. 1.概述 1.1.基于U ...

  2. jQuery拉开关闭帷幕

    查看效果:http://keleyi.com/keleyi/phtml/jqtexiao/7.htm HTML文件代码: <!DOCTYPE html PUBLIC "-//W3C// ...

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

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

  4. JavsScript+dom

    JavsScript+dom DOM(兼容性) 用于操作文档树 1.帮助我们找到标签 直接查找 间接查找 getElementById getElementsByTageName 2.标签操作 内容: ...

  5. SharePoint 2013 使用JavaScript对象模型配置智能提示

    前言 默认在VS2012/2013中编写SharePoint JavaScript 客户端对象模型,都没有智能感知的功能,用起来非常麻烦:其实,我们可以手动配置一下,让JavaScript可以进行智能 ...

  6. MyEclipse使用心得:SVN插件安装方法

    1.在线安装,打开myeclipse,help--->MyEclipse Configuration Center 2.点击Add Site 打开对话框,在对话框Name输入Svn,URL中输入 ...

  7. iOS-钥匙串中证书全部失效(证书的签发者无效)的解决办法

    今天用Xcode打包IPA文件给同事,结果提示import时,提示证书missing,找了半天没发现问题,后来打开钥匙串,发现证书全失效了!!!根证书失效了!吓死宝宝了 解决方法 首选此方法: 1.打 ...

  8. String类型传值以及对象传值

    package Virtual; class Stan{ String mm = "hello"; } class Virtual { public static void mai ...

  9. __block 和 __weak的区别

    Blocks理解: Blocks可以访问局部变量,但是不能修改 如果修改局部变量,需要加__block __block int multiplier = 7; int (^myBlock)(int) ...

  10. 基于Ruby的Watir-WebDriver自动化测试方案

    Watir-WebDriver       —— 软件测试的自动化时代 QQ群:160409929 自动化测试方案书 系统架构 该自动化测试框架分三个模块:Test用例.Control控制层.Tool ...