codevs 2594 解药还是毒药
2594 解药还是毒药
Smart研制出对付各种症状的解药,可是他一个不小心,每种药都小小地配错了一点原料,所以这些药都有可能在治愈某些病症的同时又使人患上某些别的病症(你可能会问那…那是解药还是毒药啊?)……,经过Smart的努力,终于弄清了每种药的具体性能,他会把每种药能治愈的病症和能使人患上的病症列一张清单给你,然后你要根据这张清单找出能治愈所有病症的最少药剂组合……顺便说一声,病症的数目不超过10种,而且他的药是用不完的,就是说每种药剂都可以被重复使用。
给你们的单子里第一行是病症的总数n(1≤n≤10)。第二行是药剂的种类m(0<m≤100)。
以下有m行,每行有n个数字用空格隔开,文件的第i+2行的n个数字中,如果第j个数为1,就表示第i种药可以治愈病症j(如果患有这种病的话则治愈,没有这种病则无影响),如果为0表示无影响,如果为-1表示反而能使人得上这种病(无病患上,有病无影响)。Smart制的药任何两种性能都不同。
你只要输出用的最少的药剂数就可以了,其实还有可能用尽了所有的药也不能将所有病治愈,那样的话你们只要输出“The patient will be dead.”就可以了。
3
2
1 0 1
-1 1 0
2
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 解药还是毒药的更多相关文章
- 解药还是毒药(codevs 2594)
2594 解药还是毒药 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 题解 查看运行结果 题目描述 Description Smart研制出对 ...
- codevs2594解药还是毒药(状压dp)
2594 解药还是毒药 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 题目描述 Description Smart研制出对付各种症状的解药,可是 ...
- 【BFS】【位运算】解药还是毒药
[codevs2594]解药还是毒药 Description Smart研制出对付各种症状的解药,可是他一个不小心,每种药都小小地配错了一点原料,所以这些药都有可能在治愈某些病症的同时又使人患上某些别 ...
- Hash_P1026毒药?解药?
#include <iostream> #include <cstdio> #include <algorithm> #include <cstring> ...
- 补丁vs错误(codevs 2218 错误答案)
题目描述 Description 错误就是人们所说的Bug.用户在使用软件时总是希望其错误越少越好,最好是没有错误的.但是推出一个没有错误的软件几乎不可能,所以很多软件公司都在疯狂地发放补丁(有时这种 ...
- NOI2018准备Day12
上午学了1个小时左右的指针,学了个从句子中分离单词的方法,其他的感觉没学到啥. 中午看了一会儿网络流,懵逼...... A了8道题,4道钻石.3道黄金.1道白银,自己写出了codevs"解药 ...
- java web 程序---猜数字游戏的猜了多少次的代码
思路:用setAttribute()放 ,然后直接输出 Integer str=(Integer)session.getAttribute("count"); int num3= ...
- vijosP1026毒药?解药?
hash. 怎么感觉叫状态压缩bfs比较合适呢? #include<cstdio> #include<algorithm> #include<cstring> us ...
- Tyvj3308毒药解药题解
题目大意 这些药都有可能在治愈某些病症的同一时候又使人患上某些别的病症--经过我天才的努力.最终弄清了每种药的详细性能,我会把每种药能治的病症和能使人患上的病症列一张清单给你们,然后你们要依据这张清单 ...
随机推荐
- Java实现Mysql数据库自动备份
最近项目中有一个这样的需求,要求定时备份数据库.看了一些网上的资料,了解到主要思路是是使用java中的Runtime类的exec()方法,可以直接调用windows的cmd命令,参数就是Mysql的备 ...
- ABP 初探 之 权限设计
大.小项目都要设计权限,都想设计一个通用的权限,把权限做的比较复杂,现在了解了ABP的设计思路,觉得设计很简单,但实现方法与思路耐人寻味. 本篇只介绍AbpPermissions的数据库设计,其它表结 ...
- xcode svn commit is not under version control (1) & git commit
使用Xcode提交一个第三方库时,由于包含资源文件,总是提交不了,提示报错:XXX commit is not under version control (1) 网上查了下,得知 xcode对于sv ...
- Linux系统安装NoSQL(MongoDB和Redis)步骤及问题解决办法
➠更多技术干货请戳:听云博客 如下是我工作中的记录,介绍的是linux系统下NoSQL:MongoDB和Redis的安装过程和遇到的问题以及解决办法: 需要的朋友可以按照如下步骤进行安装,可以快速安装 ...
- 2014年年度工作总结--IT狂人实录
2014年也是我人生最重要的一年,她见证了我的成长与蜕变,让我从一个迷茫的旅者踏上一条柳暗花明的路. 春宇之行 从春宇短暂的9个月,却经历常人难以想想的风风雨雨,首先要感谢春宇公司给我带来了安逸宽松的 ...
- IT软件人员的技术学习内容(写给技术迷茫中的你) - 项目管理系列文章
前面笔者曾经写过一篇关于IT从业者的职业道路文章(见笔者文:IT从业者的职业道路(从程序员到部门经理) - 项目管理系列文章).然后有读者提建议说写写技术方面的路线,所以就有了本文.本文从初学者到思想 ...
- 常用API——Math对象型、Number型
Math.abs(num) : 返回num的绝对值 Math.acos(num) : 返回num的反余弦值 Math.asin(num) : 返回num的反正弦值 Math.atan(num) : 返 ...
- angularjs结合d3js实现资源展示
转载请注明出处: 转载自Bin's Blog: angularjs & d3 实现资源展示( http://www.wenbin.cf/post/27/ ) angularjs结合d3js实 ...
- C#委托的介绍(delegate、Action、Func、predicate) --转载
来源:http://www.cnblogs.com/akwwl/p/3232679.html 委托是一个类,它定义了方法的类型,使得可以将方法当作另一个方法的参数来进行传递.事件是一种特殊的委托. 1 ...
- Oracle 11g 单实例安装文档
这里介绍在Red Hat Enterprise Linux Server release 5.7 (Tikanga)下安装ORACLE 11.2.0.1.0的过程,本文仅仅是为了写这样安装指导文档而整 ...