数组不连续取数问题(不连续取糖果)

回想最初遇到这个问题的时候,题面描述如下:

有连续编号的盒子内放着数量不等的糖果,有个强盗来打劫,不允许从两个相邻的盒子中取走糖果,问最多能获取到多少颗糖果。

起初还以为是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)
拿糖果

参考:
动态规划实例–数组不连续取的问题

发表评论

电子邮件地址不会被公开。 必填项已用*标注