1. 题目描述
题目链接:

2. 题目解析
首先创建一个 arr 数组,将原数组 nums 里的值全部映射到 arr 数组中。因为 nums 里的值可能是相邻而不相连的,但一维数组的下标是连续的。我们可以使用 arr[i] 来表示数字 i 出现次数的总和。
将数组中的数统计到 arr 中后,问题转化为在 arr 上进行一次'打家劫舍'问题。

3. 算法原理
状态表示
以某一个位置为结尾或者以某一个位置为起点。
dp[i] 表示选到 i 位置的时候,此时的最大点数分两种情况:
f[i]表示:选到i位置的时候,当前位置nums[i]必选,此时的最大点数。g[i]表示:选到i位置的时候,当前位置nums[i]不选,此时的最大点数。
状态转移方程
根据最近的一步来划分问题,到达 dp[i] 有两种情况:
f[i] = g[i-1] + arr[i]g[i]:- 当选择
i-1的位置时:f[i-1] - 当不选择
i-1的位置时:g[i-1] - 综合得:
g[i] = max(f[i-1], g[i-1])
- 当选择
初始化
把 dp 表填满不越界,让后面的填表可以顺利进行。
本题初始化为:f[0] = arr[0], g[0] = 0。
填表顺序
本题的填表顺序是:从左往右,两个表一起填。
返回值
题目要求 + 状态表示。
偷到最后一个位置分为两种情况:选和不选。
本题的返回值是:max(f[N-1], g[N-1])。
4. 代码实现
动态规划的固定四步骤:
- 创建一个
dp表



