HDU 2809 God of War(状压DP)

版权声明:没人会转的( ̄▽ ̄) https://blog.csdn.net/j2_o2/article/details/86498969
题目链接
题意

你是一名勇者,前方有一堆恶龙,你可以以任意顺序挑战恶龙。
你有以下属性,攻、防、血、附加的攻、防、血,初始经验0,每100点经验加上附加属性*1(升级)。
恶龙有以下属性,攻、防、血、经验。
每次决斗交替攻击,你必定先手,伤害计算取 m a x ( , 1 ) max(攻-防,1) ,攻防肯定不是一个人的= =!。
能杀光所有恶龙输出最大血量,不能输出一堆奇怪的英文。


话说能不能出俩勇者博弈题,勇者最后solo之类的,虽然不会写。。


思路

状压DP,DP[1<<20],每种状态01表示哪些敌人已经被打败,dp值记录最大血量。
每种状态除了血量其他都是相同的,所以不用dp另开状态,也不需要更新,每次统计下复杂度差不了多少。
正常来说,打败敌人才能取得他的经验来升级血,虽然不考虑也能A。
也许能续命?但是应该也不允许续命的。
就那continue的问题,题意这里我可能读落了?或者数据没有这种,或者我考虑有点问题。A了就行告辞。

代码
#include <bits/stdc++.h>
using namespace std;

char s[15];
struct Node
{
    int ati, def, hp, exp;
}e[25];
int dp[1<<20];

int main()
{
    int ati, def, hp, inati, indef, inhp;
    while(~scanf("%d%d%d%d%d%d",&ati,&def,&hp,&inati,&indef,&inhp))
    {
        int n;
        scanf("%d",&n);
        for(int i = 0; i < n; ++i) scanf("%s%d%d%d%d",s,&e[i].ati,&e[i].def,&e[i].hp,&e[i].exp);

        memset(dp,0,sizeof(dp));
        dp[0] = hp;
        for(int i = 0; i < (1<<n); ++i)
        {
            if(!dp[i]) continue;
            int sum = 0;
            for(int j = 0; j < n; ++j) if((1<<j)&i) sum += e[j].exp;
            int nowati = ati+sum/100*inati;
            int nowdef = def+sum/100*indef;
            for(int j = 0; j < n; ++j)
            {
                if((1<<j)&i) continue;
                int hart1 = max(nowati-e[j].def, 1);
                int hart2 = max(e[j].ati-nowdef, 1);
                int tmp = dp[i] - hart2*(e[j].hp/hart1 + (e[j].hp%hart1 != 0) - 1);
                if(tmp <= 0) continue; // 不考虑竟然都能A,但应该要考虑
                tmp += ((sum+e[j].exp)/100 - sum/100)*inhp;
                dp[i|(1<<j)] = max(dp[i|(1<<j)], tmp);
            }
        }
        if(!dp[(1<<n)-1]) printf("Poor LvBu,his period was gone.\n");
        else printf("%d\n",dp[(1<<n)-1]);
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/j2_o2/article/details/86498969
今日推荐