题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2809

题目大意:给出战神吕布的初始攻击力ATI、防御力DEF、生命值HP、每升一级增加的攻击力In_ATI,增加的防御力In_DEF和增加的生命值In_HP。然后给出n个敌人的攻击力、防御力、生命值和杀死该单位能获得的经验值EXP。  吕布的初始经验值EXP是0,初始等级level是1,每当EXP>=level*100时就会升级。

  在吕布LvBu和敌人A之间的战斗有3条规则

  1.吕布攻击A,A失去 Max(1,LvBu's ATI- A's DEF) HP;

  2.A攻击吕布,吕布失去Max(1,A'ATI- LvBu'DEF)HP;

  3.战斗持续到任意一方死亡

如果吕布能够将全部敌人杀死,并且自己不死,那么输出能够余下的最大HP,否则输出"Poor LvBu,his period was gone."

Sample Input
100 80 100 5 5 5
2
ZhangFei 95 75 100 100
XuChu 90 90 100 90
100 75 100 5 5 5
1
GuanYu 95 85 100 100
 
Sample Output
30
Poor LvBu,his period was gone.

分析:

由于涉及到最优结果 以及 单挑顺序对结果带来的影响,使用状态压缩dp来解这道题。

想讲一下思路,比如现在吕布跟三个人战斗,用1表示已经战胜这个人, 0表示没有。那个所有的情况(在不考虑顺序的情况下)就有2的3次方,8种可能,包括000。用对应的十进制表示。如图

  可见,3的状态可以由1,2来求,5可以用1,4来求,6可以用2, 4来求,7可以用3, 5, 6状态来求,这就有了一个状态转移的方程在里面了。

有些同学就想问那顺序怎么办呢。

  我们要计算3的最优状态的时候,会由1,跟2,来推出

  1状态表示打败第一个人

  2状态只表示第二个人

  那么3状态由1状态来计算的时候,就是先打第一个人再打第二个人

  而3状态由2状态来计算的时候,就是先打第二个人再打第一个人, 计算后的结果与当前的3状态的结果比较,把最优的覆盖上去就可以了。

  这个过程是不是有了一个顺序在里面了呢。

  而在代码里面,我们是由底向上计算额。比如历遍到第1个状态点的。我们可以计算上面的第3个点,跟第5个状态点,寻找的过程由位运算来实现。

代码如下:

 # include<stdio.h>
# include<string.h>
int max(int a,int b){
return a>b ?a :b;
}
struct Lvbu{
int ATI,DEF,HP,EXP,level;
}lv,dp[<<]; //dp[i]表示在在集合i下,吕布能达到的最好状态 struct Enemy{
char name[];
int ATI,DEF,HP,EXP;
}en[]; int In_ATI,In_DEF,In_HP,n; int main(){
int i,j;
while(scanf("%d%d%d%d%d%d",&lv.ATI,&lv.DEF,&lv.HP,&In_ATI,&In_DEF,&In_HP) != EOF){
lv.EXP = ; //吕布初始经验为0,初始等级为1
lv.level = ;
scanf("%d",&n);
for(i=;i<n;i++)
scanf("%s%d%d%d%d",en[i].name,&en[i].ATI,&en[i].DEF,&en[i].HP,&en[i].EXP);
int s,recent;
int endstate = <<n;
dp[] = lv; //dp[0]表示集合0,即没有攻击任何一个敌人时,吕布的状态,初始化
bool flag; for(s=; s<endstate; s++){
flag = false; //判断是否可以打败敌人
for(i=; i<n; i++){
recent = <<i;
if(s & recent){ //如果在该集合里边,吕布打败了第i个敌人
Lvbu tmp=dp[s^recent]; //取出吕布没有打败第i个人,但是打败了状态s里边的其他所有人
if(tmp.level < ) continue; //已经死亡
int dec = tmp.ATI - en[i].DEF; //吕布的攻击力
if(dec <= ) dec = ; //特殊情况 int times = en[i].HP / dec; //吕布杀死敌人的时间
if(times * dec != en[i].HP) times++; dec = en[i].ATI - tmp.DEF; //敌人的攻击力
if(dec <= ) dec = ;
tmp.HP -= dec*(times - ); //吕布受到的伤害 if(tmp.HP <= ) continue; //如果死亡,跳出 tmp.EXP += en[i].EXP; //获得该角色经验
if(tmp.EXP >= tmp.level* ){ //如果经验足够升级
int add = tmp.EXP/ - tmp.level + ; //可升多少级
tmp.level += add; //各项技能强化
tmp.ATI += add*In_ATI;
tmp.DEF += add*In_DEF;
tmp.HP += add*In_HP;
}
if(!flag || (tmp.HP>dp[s].HP) ||tmp.level>dp[s].level){ //选取最优的方案,并且置flag为真
dp[s] = tmp;
flag = true;
}
}
}
if(!flag) dp[s].level = -; //如果不能打败该集合里的敌人,那么令等级为-1
} lv = dp[endstate -]; //将所有敌人打倒的状态 (1<<n)-1
if(lv.level < )
printf("Poor LvBu,his period was gone.\n");
else
printf("%d\n",lv.HP);
}
return ;
}

HDU 2809 God of War(DP + 状态压缩)的更多相关文章

  1. HDU 1074 Doing Homework (dp+状态压缩)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1074 题目大意:学生要完成各科作业, 给出各科老师给出交作业的期限和学生完成该科所需时间, 如果逾期一 ...

  2. HDU 4336 Card Collector (期望DP+状态压缩 或者 状态压缩+容斥)

    题意:有N(1<=N<=20)张卡片,每包中含有这些卡片的概率,每包至多一张卡片,可能没有卡片.求需要买多少包才能拿到所以的N张卡片,求次数的期望. 析:期望DP,是很容易看出来的,然后由 ...

  3. hdu 4336 Card Collector(期望 dp 状态压缩)

    Problem Description In your childhood, people in the famous novel Water Margin, you will win an amaz ...

  4. HDU 1074 Doing Homework(DP状态压缩)

    题意:有n门功课需要完成,每一门功课都有时间期限以及你完成所需要的时间,如果完成的时间超出时间期限多少单位,就会被减多少学分,问以怎样的功课完成顺序,会使减掉的学分最少,有多个解时,输出功课名字典序最 ...

  5. BestCoder Round #52 (div.2) HDU 5418 Victor and World (DP+状态压缩)

    [题目链接]:pid=5418">click here~~ [题目大意]: 问题描写叙述 经过多年的努力,Victor最终考到了飞行驾照. 为了庆祝这件事,他决定给自己买一架飞机然后环 ...

  6. hdu 4057 AC自己主动机+状态压缩dp

    http://acm.hdu.edu.cn/showproblem.php?pid=4057 Problem Description Dr. X is a biologist, who likes r ...

  7. hdu 4352 数位dp + 状态压缩

    XHXJ's LIS Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total ...

  8. hdu_4352_XHXJ's LIS(数位DP+状态压缩)

    题目连接:hdu_4352_XHXJ's LIS 题意:这题花大篇篇幅来介绍电子科大的一个传奇学姐,最后几句话才是题意,这题意思就是给你一个LL范围内的区间,问你在这个区间内最长递增子序列长度恰为K的 ...

  9. 【bzoj1076】[SCOI2008]奖励关 期望dp+状态压缩dp

    题目描述 你正在玩你最喜欢的电子游戏,并且刚刚进入一个奖励关.在这个奖励关里,系统将依次随机抛出k次宝物,每次你都可以选择吃或者不吃(必须在抛出下一个宝物之前做出选择,且现在决定不吃的宝物以后也不能再 ...

  10. hdu4336 Card Collector(概率DP,状态压缩)

    In your childhood, do you crazy for collecting the beautiful cards in the snacks? They said that, fo ...

随机推荐

  1. J2EE开发常用开源框架技术(转)

    主要就我所了解的J2EE开发的框架或开源项目做个介绍,可以根据需求选用适当的开源组件进行开发.主要还是以Spring为核心,也总结了一些以前web开发常用的开源工具和开源类库 1持久层:1)Hiber ...

  2. vijos 1464 NOIP 1997 积木游戏

    背景 1997年全国青少年信息学(计算机)奥林匹克竞赛试题 第二试 描述 积木游戏 SERCOI 最近设计了一种积木游戏.每个游戏者有N块编号依次为1 ,2,…,N的长方体积木.对于每块积木,它的三条 ...

  3. C++或者C#中如何拿到一个窗口的标题

    博客搬到了fresky.github.io - Dawei XU,请各位看官挪步.最新的一篇是:C++或者C#中如何拿到一个窗口的标题.

  4. http://xss.heimaoseoer.com/TIqiri?1413093855

    http://xss.heimaoseoer.com/TIqiri?1413093855 xss教程地址

  5. Html的空格显示

    一.使用全角空格 全角空格被解释为汉字,所以不会被被解释为HTML分隔符,能够依照实际的空格数显示. 二.使用空格的替代符号 替代符号就是在须要显示空格的地方添�替代符号,这些符号会被浏览器解释为空格 ...

  6. [Angular 2] Building a Toggle Button Component

    This lesson shows you how to build a Toggle Button in Angular 2 from scratch. It covers using transc ...

  7. Android中滑屏初探 ---- scrollTo 以及 scrollBy方法使用说明

    今天给大家介绍下Android中滑屏功能的一个基本实现过程以及原理初探,最后给大家重点讲解View视图中scrollTo 与 scrollBy这两个函数的区别 . 首先 ,我们必须明白在Android ...

  8. insert into ... on duplicate key update 与 replace 区别

    on duplicate key update:针对主健与唯一健,当插入值中的主健值与表中的主健值,若相同的主健值,就更新on duplicate key update 后面的指定的字段值,若没有相同 ...

  9. C# - 系统类 - 系统接口

    ICloneable接口 ns:System 此接口只定义了一个名为Clone的方法 该方法返回一个Object对象 表示调用该方法的对象的拷贝版 IComparable接口 ns:System 此接 ...

  10. asp遇到的一些问题

    1.伪静态问题...后台设置支持, 2.数据库链接错误,也就是说  .net 功能冲突,要后台关闭 3.本机也可以设置 iis服务器 win7配置自己的IIS服务器亲自做的图文很详细 http://j ...