状态压缩DP----HDU2809
状态压缩DP的一道较不错的入门题,第二次做这类问题,感觉不是很顺手,故记录下来.
题目的意思就是吕布战群雄,先给你6个数,分别是吕布的攻击值,防御值,生命值,升级后此三值各自的增量,然后是对手的个数num,接下来是各个对手的名字,攻击值,防御值,生命值,及经验值,规定当吕布经验值每提升100,则攻击值,防御值,生命值加上各自的增量。最后若生命值大于0,输出生命值,否则输出一句话"Poor LvBu,his period was gone."。
刚开始看到此题实在看不出是用压缩DP,以为是普通的DP。但只细一想,状态数太多了并且和编号有关联,原因是:假设与吕布对战的人有三个分别是关羽,张飞,许褚,则现在问题出来了。吕布按什么顺序来对战此三人,吕布-->关羽-->张飞-->许褚,吕布-->张飞-->关羽-->许褚等等,以及战胜一人后生命值是否为零,两人呢.......?这样想着发现很乱很乱,状态多并且不好表示(这不二进制中1正好是状态压缩擅长的嘛)。于是定义状态表达式LvBu[i],i对应的二进制中1代表已和此人对战,如5=101表示分别和关羽,许褚fight了,就差张飞了。但麻烦又来了,101是先和关羽打呢,还是先和许褚打,这里要特别注意的是和谁先打的顺序可能会导致结果不同,例如我先打关羽得到的经验值少不能升级,而我先打许褚升级的经验值就足够了,很明显这两个结果的生命值肯定不会相同。那么怎么解决呢?这只要在for循环时进行更新就可以了
接下来详细解释代码,
#include <iostream>
#include <cstdio> using namespace std; struct Person{
int attck;
int defense;
int hp;
int expirence;
}LvBu[<<],Enemy[],Update;//定义结构体,并分配相应的数组,对手最多20个
int result,num; inline int max(int a,int b) //最大值函数
{
if(a>b) return a;
return b;
} void Fight()
{
int attck,defence;
int myTime,Time;
int rHp,expirence,rattack,rdef;
for(int i=;i<=result;i++)//状态
for(int j=;j<num;j++)//对手编号从0到num-1
{
if(!(i&(<<j))&&LvBu[i].hp>)//若吕布未与编号j对手交战并且生命值不为零,有对战的必要
{
attck=max(,LvBu[i].attck-Enemy[j].defense);//依题目条件吕布攻击一次对方掉attck点血
defence=max(,Enemy[j].attck-LvBu[i].defense);//对方攻击一次吕布掉defence点血
myTime=(LvBu[i].hp+defence-)/defence;//吕布可以攻击的总次数
Time=(Enemy[j].hp+attck-)/attck;//对手可以攻击的总次数
//如关羽生命值是8,吕布攻击一次造成伤害为-3,那么吕布总共可以攻击3次,那么用一行代码如何表示呢?可以先拿1单位的血出来,剩下的直接除以伤害值
if(myTime<Time) continue;//吕布先挂了,否则继续执行
rHp=(LvBu[i].hp-(Time-)*defence);//剩余生命值原本的减去代价值,Time减一的原因是对手先倒下了,原本你打我一下,我打你一下成偶数的,你走的早就打不到我了
expirence=Enemy[j].expirence+LvBu[i].expirence;//得到经验值
rattack=LvBu[i].attck;rdef=LvBu[i].defense;//之所以这样是方便后面书写 if(expirence>=)//可以升级
{
expirence-=;//付出100点经验值为代价
rattack+=Update.attck;
rdef+=Update.defense;
rHp+=Update.hp;
} if(rHp>=LvBu[i|(<<j)].hp)//这就是我先打许褚-->关羽,还是关羽-->许褚的更新了
{
LvBu[i|(<<j)].attck=rattack;
LvBu[i|(<<j)].defense=rdef;
LvBu[i|(<<j)].hp=rHp;
LvBu[i|(<<j)].expirence=expirence;
}
}
}
if( LvBu[result].hp) printf("%d\n",LvBu[result].hp);
else printf("Poor LvBu,his period was gone.\n");
}
int main()
{
while(scanf("%d %d %d %d %d %d",&LvBu[].attck,&LvBu[].defense,&LvBu[].hp,&Update.attck,&Update.defense,&Update.hp)!=EOF)
{ //输入
LvBu[].expirence=;//吕布初始经验值为0
char name[];
scanf("%d",&num);
for(int i=;i<num;i++)
scanf("%s%d%d%d%d",name,&Enemy[i].attck,&Enemy[i].defense,&Enemy[i].hp,&Enemy[i].expirence);
result=(<<num)-;//状态总数 for(int i=;i<=result;i++) LvBu[i].hp=;//初始化
Fight();//对战
}
return ;
}
以后看着复习就省事多了
状态压缩DP----HDU2809的更多相关文章
- hoj2662 状态压缩dp
Pieces Assignment My Tags (Edit) Source : zhouguyue Time limit : 1 sec Memory limit : 64 M S ...
- POJ 3254 Corn Fields(状态压缩DP)
Corn Fields Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 4739 Accepted: 2506 Descr ...
- [知识点]状态压缩DP
// 此博文为迁移而来,写于2015年7月15日,不代表本人现在的观点与看法.原始地址:http://blog.sina.com.cn/s/blog_6022c4720102w6jf.html 1.前 ...
- HDU-4529 郑厂长系列故事——N骑士问题 状态压缩DP
题意:给定一个合法的八皇后棋盘,现在给定1-10个骑士,问这些骑士不能够相互攻击的拜访方式有多少种. 分析:一开始想着搜索写,发现该题和八皇后不同,八皇后每一行只能够摆放一个棋子,因此搜索收敛的很快, ...
- DP大作战—状态压缩dp
题目描述 阿姆斯特朗回旋加速式阿姆斯特朗炮是一种非常厉害的武器,这种武器可以毁灭自身同行同列两个单位范围内的所有其他单位(其实就是十字型),听起来比红警里面的法国巨炮可是厉害多了.现在,零崎要在地图上 ...
- 状态压缩dp问题
问题:Ignatius has just come back school from the 30th ACM/ICPC. Now he has a lot of homework to do. Ev ...
- BZOJ-1226 学校食堂Dining 状态压缩DP
1226: [SDOI2009]学校食堂Dining Time Limit: 10 Sec Memory Limit: 259 MB Submit: 588 Solved: 360 [Submit][ ...
- Marriage Ceremonies(状态压缩dp)
Marriage Ceremonies Time Limit:2000MS Memory Limit:32768KB 64bit IO Format:%lld & %llu ...
- HDU 1074 (状态压缩DP)
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=1074 题目大意:有N个作业(N<=15),每个作业需耗时,有一个截止期限.超期多少天就要扣多少 ...
- HDU 4511 (AC自动机+状态压缩DP)
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=4511 题目大意:从1走到N,中间可以选择性经过某些点,比如1->N,或1->2-> ...
随机推荐
- Timer的异常
定时任务用Timer实现有可能出现异常,因为它是基于绝对时间而不是相对时间进行调度的.当环境的系统时间被修改后,原来的定时任务可能就不跑了.另外需要注意一点,捕获并处理定时任务的异常.如果在Timer ...
- $GLOBALS超级全局变量(PHP学习)
1.$GLOBALS是一个数组,里面有所有的全局变量 2.$GLOBALS是超级全局变量,函数内部可以通过它直接操作全局变量.(严重不推荐,因为违反了封装原则) 3.通过$GLOBALS操作全局变量, ...
- webservice有关application/xop+xml的异常
今天同事调用一个webservice时返回类似错误 响应消息的内容类型 multipart/related; type="application/xop+xml"; boundar ...
- 【转】JMeter 聚合报告之90% Line参数说明
其实要说明这个参数的含义非常简单,可能你早就知道他的含义,但我对这个参数一直有误解,而且还一直以为是“真理”,原于一次面试,被问到了这个问题,所以引起我这个参数的重新认识. 先说说我错误的认识: 我一 ...
- ES之一:Elasticsearch6.4 windows安装 head插件ik分词插件安装
准备安装目标:1.Elasticsearch6.42.head插件3.ik分词插件 第一步:安装Elasticsearch6.4 下载方式:1.官网下载 https://www.elastic.co/ ...
- 拦截导弹简单版(读入一串整数时getline(cin,s) stringstream is(s);)
拦截导弹简单版 时间限制: 1 Sec 内存限制: 128 MB提交: 40 解决: 16[提交][状态][讨论版][命题人:外部导入] 题目描述 某国为了防御敌国的导弹袭击,发展出一种导弹拦截系 ...
- 摆花 (DP动态规划)
2012_p3 摆花 (flower.cpp/c/pas) 时间限制: 1 Sec 内存限制: 128 MB提交: 17 解决: 10[提交][状态][讨论版][命题人:外部导入] 题目描述 3. ...
- 杂项:UN-标准通用置标语言
ylbtech-杂项:标准通用置标语言 1.返回顶部 2.返回顶部 3.返回顶部 4.返回顶部 5.返回顶部 6.返回顶部 7.返回顶部 8.返回顶部 9.返回顶部 ...
- Git 学习小问题记录
最近一直使用Git在管理代码,但是的确不规范,今天开始恶补Git常用命令.实际今天的任务是需要从master牵出一条branch.心想着这个简单只补一下创建分支以及merge的这边的命令就可以了,于是 ...
- PL/SQL 训练09--面向对象
---对象基本声明.实现.使用--对象类型,类似与JAVA中的类,通俗的讲,就是捆绑了相关函数和过程的记录类型. ---对象声明 --create type 创建一个对象类型的规范部分 create ...