奇安信暑期实习笔试----武松打虎

149 阅读1分钟

不知道写的对不对

武松的血量为 Hp,攻击力为 Att,n只老虎的血量为 h[0],h[1],…,h[n-1],攻击力为 a[0],a[1],…,a[n-1]。每个回合武松选择一只老虎进行攻击,使其生命力下降 Att 点,若老虎生命值小于等于 0 则死亡,否则老虎会进行还击,使武松降低老虎攻击力点生命值。

第 i 只老虎身上背负 m[i] 的赏金,若武松将其打死则可以领取赏金。同时武松可以随时选择不打了,不要领赏金。   问武松最多能活着(Hp>0)得到多少赏金。

示例 1 输入: 1, 1, [1,1,2,1], [1, 1, 1, 1], [1, 2, 4, 8] 示例 1

输出: 11

说明: 对于第 0,1,3 只老虎,武松可以直接打死,自己不会掉血,而对于第 2 只老虎,武松会被老虎反击致死。因此能够获得的最大的悬赏金为 11 = 1 + 2 + 8。

public static int maxReward(int Hp, int Att, int[] h, int[] a, int[] m) {
    int n = h.length;
    int[][] dp = new int[n + 1][Hp + 1];

    for (int i = 1; i <= n; i++) {
        for (int j = Hp; j >= 0; j--) {
            int rest = restFlood(j, Att, h[i - 1], a[i - 1]);
            // 打第i只老虎
            if (rest > 0) {
                dp[i][j] = Math.max(dp[i - 1][rest] + m[i - 1], dp[i - 1][j]);
            }
            // 不打第i只老虎
            dp[i][j] = Math.max(dp[i][j], dp[i - 1][j]);
        }

    }

    return dp[n][Hp];
}

public int restFlood(int hp_wu, int att_wu, int hp_tiger, int att_tiger) {
    while (hp_wu > 0 && hp_tiger > 0) {
        hp_tiger -= att_wu;
        if (hp_tiger <= 0) return hp_wu;
        hp_wu -= att_tiger;
    }
    return hp_wu;
}