diff --git a/notes/剑指 offer 题解.md b/notes/剑指 offer 题解.md index fd758318..3103295b 100644 --- a/notes/剑指 offer 题解.md +++ b/notes/剑指 offer 题解.md @@ -56,6 +56,7 @@ * [44. 数字序列中的某一位数字](#44-数字序列中的某一位数字) * [45. 把数组排成最小的数](#45-把数组排成最小的数) * [46. 把数字翻译成字符串](#46-把数字翻译成字符串) + * [47. 礼物的最大价值](#47-礼物的最大价值) * [49. 丑数](#49-丑数) * [50. 第一个只出现一次的字符位置](#50-第一个只出现一次的字符位置) * [51. 数组中的逆序对](#51-数组中的逆序对) @@ -1485,6 +1486,41 @@ public int getTranslationCount(String number) { } ``` +## 47. 礼物的最大价值 + +**题目描述** + +在一个 m * n 的棋盘的每一个格都放有一个礼物,每个礼物都有一定价值(大于 0)。从左上角开始拿礼物,每次向右或向下移动一格,直到右下角结束。给定一个棋盘,求拿到礼物的最大价值。例如,对于如下棋盘 + +``` +1 10 3 8 +12 2 9 6 +5 7 4 11 +3 7 16 5 +``` + +礼物的最大价值为 1+12+5+7+7+16+5=53。 + +**解题思路** + +应该用动态规划求解,而不是深度优先搜索,深度优先搜索过于复杂,不是最优解。 + +```java +public int getMaxValue(int[][] values) { + if (values == null || values.length == 0 || values[0].length == 0) return 0; + int m = values.length; + int n = values[0].length; + int[] dp = new int[n]; + for (int i = 0; i < m; i++) { + dp[0] += values[i][0]; + for (int j = 1; j < n; j++) { + dp[j] = Math.max(dp[j], dp[j - 1]) + values[i][j]; + } + } + return dp[n - 1]; +} +``` + ## 49. 丑数 **题目描述**