HDU 2809 God of War(DP + 状态压缩)
题目链接: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."
分析:
由于涉及到最优结果 以及 单挑顺序对结果带来的影响,使用状态压缩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 + 状态压缩)的更多相关文章
- HDU 1074 Doing Homework (dp+状态压缩)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1074 题目大意:学生要完成各科作业, 给出各科老师给出交作业的期限和学生完成该科所需时间, 如果逾期一 ...
- HDU 4336 Card Collector (期望DP+状态压缩 或者 状态压缩+容斥)
题意:有N(1<=N<=20)张卡片,每包中含有这些卡片的概率,每包至多一张卡片,可能没有卡片.求需要买多少包才能拿到所以的N张卡片,求次数的期望. 析:期望DP,是很容易看出来的,然后由 ...
- hdu 4336 Card Collector(期望 dp 状态压缩)
Problem Description In your childhood, people in the famous novel Water Margin, you will win an amaz ...
- HDU 1074 Doing Homework(DP状态压缩)
题意:有n门功课需要完成,每一门功课都有时间期限以及你完成所需要的时间,如果完成的时间超出时间期限多少单位,就会被减多少学分,问以怎样的功课完成顺序,会使减掉的学分最少,有多个解时,输出功课名字典序最 ...
- BestCoder Round #52 (div.2) HDU 5418 Victor and World (DP+状态压缩)
[题目链接]:pid=5418">click here~~ [题目大意]: 问题描写叙述 经过多年的努力,Victor最终考到了飞行驾照. 为了庆祝这件事,他决定给自己买一架飞机然后环 ...
- hdu 4057 AC自己主动机+状态压缩dp
http://acm.hdu.edu.cn/showproblem.php?pid=4057 Problem Description Dr. X is a biologist, who likes r ...
- hdu 4352 数位dp + 状态压缩
XHXJ's LIS Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total ...
- hdu_4352_XHXJ's LIS(数位DP+状态压缩)
题目连接:hdu_4352_XHXJ's LIS 题意:这题花大篇篇幅来介绍电子科大的一个传奇学姐,最后几句话才是题意,这题意思就是给你一个LL范围内的区间,问你在这个区间内最长递增子序列长度恰为K的 ...
- 【bzoj1076】[SCOI2008]奖励关 期望dp+状态压缩dp
题目描述 你正在玩你最喜欢的电子游戏,并且刚刚进入一个奖励关.在这个奖励关里,系统将依次随机抛出k次宝物,每次你都可以选择吃或者不吃(必须在抛出下一个宝物之前做出选择,且现在决定不吃的宝物以后也不能再 ...
- hdu4336 Card Collector(概率DP,状态压缩)
In your childhood, do you crazy for collecting the beautiful cards in the snacks? They said that, fo ...
随机推荐
- Esper系列(十)NamedWindow语法delete、Select+Delete、Update
On-Delete With Named Windows 功能:在Named Windows中删除事件. 格式: 1 , 4 field_b = win.field_a, 5 field_ ...
- javascript数组操作汇总
javascript之数组操作 - 不悔的青春 - 博客园 1.数组的创建 var arrayObj = new Array(); //创建一个数组 var arrayObj = new Array( ...
- makeKeyAndVisible的功能
makeKeyAndVisible的作用 [self.window makeKeyAndVisible] 由于iPhone是单窗口程序,所以也就只有这么一个Window对象,而且是UIWindow,不 ...
- 8-15-Exercise
8-15-小练 这次的题目......只觉得泪奔啊......T T A.HDU 1042 N! 因为0<=n<=1000,故一定要用数组或字符串[同样因为n<=1000故用数组 ...
- C#编译器怎么检查代码是否会执行
博客搬到了fresky.github.io - Dawei XU,请各位看官挪步.最新的一篇是:C#编译器怎么检查代码是否会执行.
- JAVA调用操作javascript (JS)工具类
import java.io.BufferedReader;import java.io.FileNotFoundException;import java.io.FileReader;import ...
- RedHat Enterprise Linux 6.4使用Centos 6 的yum源 分类: 服务器搭建 Nginx 2015-07-14 14:11 5人阅读 评论(0) 收藏
转载自:http://blog.sina.com.cn/s/blog_50f908410101cto6.html 思路:卸载redhat自带yum,然后下载centos的yum,安装后修改配置文件 1 ...
- careercup-递归和动态规划 9.7
9.7 编写函数,实现许多图片编辑软件都支持的“填充颜色”功能.给定一个屏幕(以二维数组表示,元素为颜色值).一个点和一个新的颜色值,将新颜色值填入这个点的周围区域,直到原来的颜色值全部改变. 类似l ...
- 在其它路径新建cocos2d-x项目
打开vs2010程序,然后选择“文件—新建—项目”,如图 改了一下位置,放在D:\Program Files\cocos2d-x\ ,确定 然后点下一步 这个程序不需要物理引擎,所以可以把上面红色的圈 ...
- ls -l命令详解
输入: ls -l 输出: -rwxr-xr-x root root May : b 第一个字段(1个字符):文件类型 - :普通文件 d:目录文件 b:块设备文件(block) c:字符设备文件(c ...