LintCode刷题——卡牌游戏 II(0-1背包)

题目描述

你跟你的朋友在玩一个卡牌游戏,总共有 n 张牌。每张牌的成本为 cost[i] 并且可以对对手造成 damage[i] 的伤害。你总共有 totalMoney 元并且需要造成至少 totalDamage 的伤害才能获胜。每张牌只能使用一次,判断你是否可以取得胜利。

样例

样例1

输入:
cost = [1,2,3,4,5]
damage = [1,2,3,4,5]
totalMoney = 10
totalDamage = 10

输出: true
样例说明: 我们可以使用 [1,4,5] 去造成10点伤害,总花费为10。

Example2

输入:
cost = [1,2]
damage = [3,4]
totalMoney = 10
totalDamage = 10

输出: false
样例说明:我们最多只能造成7点伤害。
标签
背包型动态规划       动态规划
 

思路

动态规划

  1、状态:0-1背包 dp[i][j] 表示前i个卡牌总共有j元能造成的最多伤害

  2、状态转移方程:dp[i][j] = Math.max(dp[i - 1][j], dp[i - 1][j - cost[i - 1]] + damage[i - 1])

 

AC代码

 1 public class Solution {
 2     /**
 3      * @param cost: costs of all cards
 4      * @param damage: damage of all cards
 5      * @param totalMoney: total of money
 6      * @param totalDamage: the damage you need to inflict
 7      * @return: Determine if you can win the game
 8      */
 9     public boolean cardGame(int[] cost, int[] damage, int totalMoney, int totalDamage) {
10         // Write your code here
11         int n = cost.length;
12         if (n == 0 && totalDamage > 0) {
13             return false;
14         }
15 
16         if (totalDamage > 0 && totalMoney == 0) {
17             return false;
18         }
19 
20         if (totalDamage == 0) {
21             return true;
22         }
23 
24         // 0-1背包 dp[i][j] 表示前i个卡牌总共有j元能造成的最多伤害
25         int[][] dp = new int[n + 1][totalMoney + 1];
26 
27         // 初始化
28         dp[0][0] = 0;
29 
30         for (int i = 1; i <= n; i++) {
31             dp[i][0] = 0;
32             dp[0][i] = 0;
33         }
34 
35         for (int i = 1; i <= n; i++) {
36             for (int j = 1; j <= totalMoney; j++) {
37                 // 设置为无穷小,因为是选最大值
38                 // 这里有一点很坑,其实是要找其最大值(不要被题目的至少所迷惑),然后后面比较的时候是用大于等于
39                 dp[i][j] = Integer.MIN_VALUE;
40                 if (cost[i - 1] > j) {
41                     dp[i][j] = dp[i - 1][j];
42                 } else {
43                     dp[i][j] = Math.max(dp[i - 1][j], dp[i - 1][j - cost[i - 1]] + damage[i - 1]);
44                 }
45             }
46         }
47 
48         // 在这里体现出题目中至少这个词的意义
49         if (dp[n][totalMoney] >= totalDamage) {
50             return true;
51         } else {
52             return false;
53         }
54     }
55 }

原题链接:https://www.lintcode.com/problem/1538/

posted @ 2021-04-06 17:44  没有你哪有我  阅读(190)  评论(0编辑  收藏  举报