回想最初遇到这个问题的时候,题面描述如下:
有连续编号的盒子内放着数量不等的糖果,有个强盗来打劫,不允许从两个相邻的盒子中取走糖果,问最多能获取到多少颗糖果。
起初还以为是leetcode上的分糖果问题,其实不一样。后来遇到了leetcode打家劫舍方知是这题,出题人很巧妙的包装了问题。
一、思路:
具象分析这个问题,可以如下表述:
给定一个维数组,长度为N。不允许取连续的两个数,求取到数字的最大和
例:输入:[1,3,5,2,1,9,4,3,7]
答案为:1+5+9+7=22
二、算法:
0、采用动态规划,计算取每个盒子最大和, 状态dp[i]
1、初始化第一个状态 dp[0] = $arr[0];
2、初始化第二个状态 dp[1] = max(dp[0], $arr[1]);
3、状态转移方程: 取了当前数,就不能取前一个 dp[i] = max(dp[i-1], dp[i – 2] + $arr[i]);
三、PHP实现
class Solution { public static function total($arr) { $len = count($arr); if ($len < 1) { return 0; } $dp = []; $i = 0; $dp[0] = $arr[0]; $dp[1] = max($dp[0], $arr[1]); for ($i = 2; $i < $len; $i++) { $dp[$i] = max($dp[$i - 1], $dp[$i - 2] + $arr[$i]); } return array_pop($dp); } } $case1 = [1, 5, 9]; $res = Solution::total($case1); var_dump($res); $case2 = [1, 3, 5, 2, 1, 9]; $res = Solution::total($case2); var_dump($res); $case3 = [1, 3, 5, 2, 1, 9, 4, 3, 7]; $res = Solution::total($case3); var_dump($res);
以上输出
int(10) int(15) int(22)
四、发散
其他取糖果问题
DP-动态规划算法实例:拿糖果问题
FZU2136–取糖果 (线段树+RMQ)
拿糖果
参考:
动态规划实例–数组不连续取的问题