zoukankan      html  css  js  c++  java
  • HDU 2809 God of War

    状压DP。我认为是数据水了,用打死了哪几只作为状态,AC代码只需要保存当前状态的最大血量,完全没有考虑攻击力大小。

    个人认为正确DP应该这样的:dp[状态][等级],但这样写不能AC,时间复杂度会很大,但答案应该是正确的。

    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<string>
    #include<algorithm>
    #include<iostream>
    using namespace std;
    
    struct X
    {
        int HP;
        int ATI;
        int DEF;
        int e;
        int lv;
    } dp[(1 << 20) + 10], A[25];
    
    int In_ATI, In_DEF, In_HP;
    int ATI, DEF, HP;
    int n;
    int base[25];
    
    int MAX(int a, int b)
    {
        if (a>b) return a;
        return b;
    }
    
    void read()
    {
        scanf("%d", &n);
        for (int i = 0; i<n; i++)
        {
            string name;
            cin >> name;
            scanf("%d%d%d%d", &A[i].ATI, &A[i].DEF, &A[i].HP, &A[i].e);
        }
    }
    
    void init()
    {
        dp[0].ATI = ATI, dp[0].DEF = DEF, dp[0].HP = HP;
        dp[0].e = 0, dp[0].lv = 1;
    
        for (int i = 1; i<(1 << n); i++) dp[i].HP = -1;
    }
    
    int f(int num1, int num2)
    {
        int A1 = MAX(1, dp[num1].ATI - A[num2].DEF);
        int A2 = MAX(1, A[num2].ATI - dp[num1].DEF);
    
        int HP1 = dp[num1].HP;
        int HP2 = A[num2].HP;
    
        int tot1, tot2;
        if (HP2%A1 == 0) tot1 = HP2 / A1;
        else tot1 = HP2 / A1 + 1;
    
        if (HP1%A2 == 0) tot2 = HP1 / A2;
        else tot2 = HP1 / A2 + 1;
    
        if (tot1 <= tot2) return HP1 - A2*(tot1 - 1); //返回吕布打完后的血量
        return -1; //返回吕布被打死
    }
    
    void work()
    {
        for (int i = 1; i<(1 << n); i++)
        {
            int tot = 0, tmp = i;
            while (tmp) base[tot++] = tmp % 2, tmp = tmp / 2;
    
            for (int j = 0; j<tot; j++)
            {
                if (base[j])
                {
                    int pre = i - (1 << j);
                    if (dp[pre].HP == -1) continue;
    
                    int lx = f(pre, j);
                    if (lx == -1) continue;
    
                    int hp = lx;
                    int e = dp[pre].e + A[j].e;
                    int lv = dp[pre].lv;
                    int ati = dp[pre].ATI;
                    int def = dp[pre].DEF;
    
                    if (e >= 100 * dp[pre].lv)
                    {
                        hp = hp + In_HP;
                        ati = ati + In_ATI;
                        def = def + In_DEF;
                        lv++;
                    }
    
                    if (hp>dp[i].HP)
                    {
                        dp[i].e = e;
                        dp[i].lv = lv;
                        dp[i].HP = hp;
                        dp[i].ATI = ati;
                        dp[i].DEF = def;
                    }
                }
            }
        }
    
        if (dp[(1 << n) - 1].HP == -1) printf("Poor LvBu,his period was gone.
    ");
        else printf("%d
    ", dp[(1 << n) - 1].HP);
    }
    
    int main()
    {
        while (~scanf("%d%d%d%d%d%d", &ATI, &DEF, &HP, &In_ATI, &In_DEF, &In_HP))
        {
            read();
            init();
            work();
        }
        return 0;
    }
  • 相关阅读:
    用C# WebClient类 提交数据
    a标签弹出 文件上载框
    C中 #define
    五款专业文本编辑器比较(转贴)
    IE和Firefox(火狐)在JavaScript方面的不兼容及统一方法总结
    全球历史票房排行
    ASP调用带参数存储过程的几种方式
    VB6.0如何使用正则表达式
    实现VB与EXCEL的无缝连接
    初识Firebug 全文 — firebug的使用
  • 原文地址:https://www.cnblogs.com/zufezzt/p/5200104.html
Copyright © 2011-2022 走看看