标签:
题目大意:貌似是一个游戏,首先给出卢布的攻击,防御,还有血量,再给出每升一级增加的攻击防御还有血量,然后又N个敌人,杀死每个敌人都会得到一些经验,求杀死完所有敌人时剩余的最大血量。
分析:因为敌人比较少,最多只有20个,所以状态最多有2^20种,用dp[i]表示状态为i的时候的最大剩余血量,然后模拟战斗即可。
代码如下:
==========================================================================================================================
#include<stdio.h> #include<string.h> #include<algorithm> #include<math.h> using namespace std; const int Bit = 20; const int MaxExp = 100; int dp[1<<Bit];///表示剩余的最大血量 struct Enemies {///敌人的属性 int ATI, DEF, HP, Exp;///初始攻击,防御,血量, 经验值 }p[Bit]; struct LvBu {///吕布的个人属性 int ATI, DEF, HP, Exp;///初始攻击,防御,血量 int In_ATI,In_DEF,In_HP;///每升一级增加的攻击防御血量 LvBu newLvBu(int x, int hp, Enemies p[]) {///状态x时候吕布的属性,血值 LvBu result; result.HP = hp;///血量等于传的最大血量值 int sumExp=0; for(int i=0; x; i++) { if(x & 1) sumExp += p[i].Exp; x >>= 1; } int Lv = sumExp / MaxExp;///计算级别 result.ATI = ATI + In_ATI * Lv; result.DEF = DEF + In_DEF * Lv; result.Exp = sumExp % MaxExp; result.In_HP = In_HP; return result; } int Fight(const Enemies &p) {///如果吕布能打过,返回剩余的血量,如果不能打过返回0 int Kill_En = p.HP, Kill_Lb = HP;///杀死敌人需要的次数,杀死吕布需要的次数 if(ATI > p.DEF) {///如果卢布的攻击大于敌人的防御 Kill_En = p.HP / (ATI-p.DEF) + (p.HP%(ATI-p.DEF) ? 1 : 0); } if(p.ATI > DEF) {///如果敌人的攻击大于卢布的防御 Kill_Lb = HP / (p.ATI-DEF) + (HP%(p.ATI-DEF) ? 1 : 0); } if(Kill_En == 0) Kill_En = 1;///防止对方血量刚开始就为0 int LastHP = 0; if(Kill_En <= Kill_Lb) {///因为吕布先攻击,所以如果攻击次数小于或等于敌人的话,那么就可以杀死对方 if(p.ATI > DEF) LastHP = HP - (Kill_En-1) * (p.ATI-DEF); else LastHP = HP - (Kill_En-1);///不破防,强制每次掉一滴血 if(p.Exp+Exp >= MaxExp) LastHP += In_HP;///判断杀死这个敌人后是否能升级 } return LastHP; } }; int main() { LvBu Lb; while(scanf("%d%d%d%d%d%d", &Lb.ATI, &Lb.DEF, &Lb.HP, &Lb.In_ATI, &Lb.In_DEF, &Lb.In_HP) != EOF) {///吕布的个人属性 int i, j, N; memset(dp, false, sizeof(dp)); scanf("%d", &N); for(i=0; i<N; i++) {///敌人的属性 scanf("%*s%d%d%d%d", &p[i].ATI, &p[i].DEF, &p[i].HP, &p[i].Exp); } dp[0] = Lb.HP; int M = 1<<N; for(i=0; i<M; i++) { if(dp[i]) {///如果有血量,先构造当前血量时卢布的状态 LvBu newLb = Lb.newLvBu(i, dp[i], p); for(j=0; j<N; j++) { if( !(i & (1<<j)) ) {///第j位为0,表示敌人j存活,计算杀死敌人j剩余的血量 dp[i|(1<<j)] = max(dp[i|(1<<j)], newLb.Fight(p[j])); } } } } if(dp[(1<<N)-1] == 0) printf("Poor LvBu,his period was gone.\n"); else printf("%d\n", dp[(1<<N)-1]); } return 0; }
God of War - HDU 2809(状态压缩+模拟)
标签:
原文地址:http://www.cnblogs.com/liuxin13/p/4850114.html