窃贼打劫
2018-08-09 本文已影响0人
stoneyang94
题目
假设你是一个专业的窃贼,准备沿着一条街打劫房屋。每个房子都存放着特定金额的钱。你面临的唯一约束条件是:相邻的房子装着相互联系的防盗系统,且 当相邻的两个房子同一天被打劫时,该系统会自动报警。
给定一个非负整数列表,表示每个房子中存放的钱, 算一算,如果今晚去打劫,你最多可以得到多少钱 在不触动报警装置的情况下。
样例
给定 [3, 8, 4], 返回 8.
要求
O(n) 时间复杂度 且 O(1) 存储。
思路
假设你来到一个房子面前,你有两种选择:打劫或者放弃。
如果打劫,那么此时的打劫金额等于从第一个房子至上上一个房子打劫所获得的金额加上打劫该房子获得的金额。
如果放弃,此时的金额依旧等从第一个房子到上一个房子打劫所获的金额。
动态规划
- 方程:f[n]=max(f[n-1],f[n-2]+money[n]);
- n表示第n个房子,n-1表示上一个房子,n-2表示上上一个房子。
- f[n]表示打劫前n个房子所获得的最大金额。
代码
- @param A: An array of non-negative integers.
- return: The maximum amount of money you can rob tonight
public class Solution {
public static long houseRobber(int[] A) {
int len = A.length;
// dp[i] 表达打劫i房间为止所活动的收获 ,与dp[i-2] dp[i-3]有关
if(len ==0)
return 0;
if(1==len)
return A[0];
long dp[] = new long[len];
dp[0]=A[0];
dp[1]= Math.max(A[0],A[1]);
for(int i=2;i<len;++i){
dp[i]=Math.max(dp[i-2]+A[i],dp[i-1]);
}
return dp[len-1];
}
public static void main(String[] args) {
int a[] = new int[]{3,8,4};
System.out.println(houseRobber(a));
}
}
输出:8