动态规划-不回溯
题目
盗贼准备打家劫舍,已知有n个房屋,每个房屋中有数量不等的财宝,有一个盗贼希望从房屋中取果最甘4房屋中有报警器,同时从相邻的两个房屋中盗取财宝就会触发报警器,计算在不触发报警器的前提下多可获取多少财宝。
例如: 5,2,6,3,1,7--->结果为18
求解
思路
动规的题关键在于如何建立动态方程
思考dp[i]的含义,本题内dp[i]表示 前 i 个房屋的最优解
- dp[1]=num[0]=5
- dp[2]: 比较num[0] 和num[1]的大小(不能选择相邻的),num[0]>num[1]
- dp[2]=num[0]=dp[1]=5
- dp[3]:比较num[0]+num[2]和num[1]的大小,看是否选择num[2],选择num[2]即为dp[1]+num[2]=5+6=11,不选择num[2]为dp[2]=5。由此可见,dp[3]=11。
- 依次类推...
代码
#include<iostream>
#include<vector>
using namespace std;
int fn(vector<int>& num)
{
if (num.size() == 0)
return 0;
if (num.size() == 1)
return num[0];
vector<int> dp(num.size() + 1, 0);//+1??
dp[1] = num[0];
dp[2] = max(num[0], num[1]);
for (int i = 3; i <= num.size(); i++)
{
dp[i] = max(dp[i - 1], dp[i - 2] + num[i-1]);
}
return dp[num.size()];
}
力扣
代码
class Solution {
public:
int rob(vector<int>& nums) {
//动态规划
if(nums.size()==0)
return 0;
if(nums.size()==1)
return nums[0];
//int dp[i];
vector<int>dp(nums.size()+1,0);//dp下标是从1开始的
dp[1]=nums[0];
dp[2]=max(dp[1],nums[1]);//)nums[1];
for(int i=3;i<nums.size()+1;i++)//dp下标是从1开始的
{
dp[i]=max(dp[i-1],dp[i-2]+nums[i-1]);
}
return dp[nums.size()];
}
};
运行结果