【c++】打家劫舍(动态规划)

打家劫舍

题目难度:高阶

时间限制:1000ms

内存限制:256mb

题目描述

你是一个专业的小偷,计划偷窃沿街的房屋。每间房内都藏有一定的现金,影响你偷窃的唯一制约因素就是相邻的房屋装有相互连通的防盗系统,如果两间相邻的房屋在同一晚上被小偷闯入,系统会自动报警。

给定一个代表每个房屋存放金额的非负整数数组,计算你在不触动警报装置的情况下,能够偷窃到的最高金额。

输入格式

第一行一个整数n,表示房屋的数量。

第二行n个整数,空格隔开,依次表示沿街n个房屋内的现金数量。

输出格式

一个整数,表示小偷能得到的最高金额。

样例数据
输入样例
复制代码
4
1 2 3 1
输出样例
复制代码
4
数据范围

对100%的数据,2<n≤10^5,每个房屋内金额不超过1000。


思路:

不要被这个高阶的难度吓到了,其实很简单

首先,我们知道这是动态规划,所以定义一个数组,long long dpn+10;

dpi代表从第一家一直偷到第i家最多能投到多少钱(比如dp5表示从第一家到第五家最多偷几块钱)

好的,现在我们只要知道,dpi等于什么就好了(状态转移方程)

分析一下,假设我们知道了dp1到dp4的所有结果,现在我们要求dp5,应该怎么求呢?

因为我们不能偷相邻的房间,所以现在我们求dp5有两种选择:

1、dp5=dp4,这是什么意思呢?就是说,我们从第一间房子偷到第四间房子,已经偷了很多钱(比如已经偷了114514元钱),如果从第一间房子偷到第三间房子,再偷第五间房子,可能只能偷到1元,这种时候,最好的情况就是偷到第四间房子停下来,不偷第五间了,所以dp5只能等于偷到第四件的最大钱数

2、dp5=dp3+a5,这又是什么意思呢?就是从第一间房子偷到第三间房子,再偷第五间房子,这样偷到的钱可能会比偷到第四间房子偷的多,所以我们就会选择能偷更多的2号方案(就是从第一间房子偷到第三间房子,再偷第五间房子)

现在我们知道了,已经有两种选择,所以dpi=max(dpi-2+ai,dpi-1);

现在,我们还需要解决一个问题:

如果dpi=max(dpi-2+ai,dpi-1);那么当i=3或者4时,需要用到dp1或dp2,但求dp1要求出dp1-2=dp-1,但我们不可能有dp-1这个数组,所以,dp1和dp2要我们提前求出来

dp1就等于第一间房子的钱数(从第一间房子偷到第一间房子,我们最多只能把第一间房子的钱全拿走)

dp2=max(a1,a2);从第一间房子偷到第二间房子,我们只能偷一间房子,否则就会触发警报,只能偷第一间或第二间

那么,我们现在就能写出程序了


代码:

cpp 复制代码
#include<bits/stdc++.h>
using namespace std;
int main(){
	long long n;
	cin>>n;
	long long a[n+10],dp[n+10];//a存每间房子的钱数 
	for(int i=1;i<=n;i++){
		cin>>a[i];//读入 
	}
	for(int i=1;i<=n;i++){
		if(i==1){//提前处理dp[1] 
			dp[i]=a[i];
		}else if(i==2){//提前处理dp[2] 
			dp[i]=max(a[i-1],a[i]);
		}else{//否则就是正常状态了,直接把状态转移方程抄进去 
			dp[i]=max(dp[i-2]+a[i],dp[i-1]);
		}
	}
	cout<<dp[n];//输出从第一间房子偷到第n间房子最多偷多少 
	return 0;
}
相关推荐
倒头就睡的小比特1 天前
算法竞赛C++常用的STL
c++·算法
weilx12341 天前
C++笔记-文件IO-<fcntl.h>
c++
小羊没烦恼!1 天前
初探性能优化——2个月到4小时的性能提升
java·开发语言·windows·算法·c#
猎头南楼1 天前
知识社区推荐系统实践:新用户冷启动与长短期兴趣建模的挑战 资深推荐算法工程师
人工智能·深度学习·算法·机器学习
Smileyqp沛沛1 天前
前端?C++ ?较大差异基础罗列
c++·基础·前端转c++
C语言小火车1 天前
C/C++ 为什么需要编译器?
开发语言·c++
旖旎夜光1 天前
力控面试题 01.01: 判定字符是否唯一(位运算) —— 题解
c++·学习·算法·leetcode·力控
wzdark1 天前
大规模并行计算中的负载均衡算法研究4
算法
吞下星星的少年·-·1 天前
C++ 萌新语法入门篇
c++·算法比赛
Because_of_Her11 天前
并查集-听课笔记
笔记·算法·并查集