题目:你是一名专业强盗,计划沿着一条街打劫。每间房屋都储存有一定金额的钱,唯一能阻止你打劫的约束条件就是房屋之间有安全系统相连,如果同一个晚上有两间相邻的房屋被闯入,它们就会自动联络警察,因此不可以打劫相邻的房屋。 给出一个表示每个房子的金额的非负整数的列表,确定你今天晚上可以抢救的最大金额,而不提醒警察。 思路:加入int[] sum={1,2,3,4},在不能抢相邻房子的前提下, 4栋房子我们可以最多抢2栋,即挑选出两个加和最大值 ,在int[] sum={1,2,3,4,5},5栋房子时我们可以最多可以抢3栋,但是不见得三栋的的和比抢两栋的钱数多。所以要找最大值,又要不相邻,我们需要用到用状态转移方程:sum[i] += Math.max(sum[i-2], sum[i-3]); 即抢第四栋房子时,要在去除抢第一栋或抢第二栋时的最大值。(这个的sum[i-2],并不是那个i-2索引的值而是通过状态转移方程求出的和)。 代码
public static int robber(int[] sum){ if (sum== null || sum.length == 0) { return 0; } //如果只有一个元素,返回这个元素值 if(sum.length==1){ return sum[0]; } else if(sum.length==2){ //如果有两个元素,返回其中较大的值 return Math.max(sum[0], sum[1]); }else if(sum.length==3){ //如果有三个元素,比较第一个元素和第三个元素之和与第二个元素的值,返回较大者 return Math.max(sum[0]+sum[2], sum[1]); } //把第一个和第三个元素的和赋给第三个元素,以便以后比较 if (sum.length > 3) { sum[2] += sum[0]; } //从第四个元素开始处理就需要用到公式了,也是从第四个开始重新赋值,元素少于四的时候,公式不成立 int i = 3; for(;i<sum.length;i++){ sum[i] += Math.max(sum[i-2], sum[i-3]); } //举个例子:如有4个元素,i=3,执行一次循环之后(这个时候i=4):最后一个元素=最后一个元素+前两个中较大的; return Math.max(sum[i-1], sum[i-2]);//再比较最后一个和倒数第二个 }