力扣75——一维动态规划

总结leetcode75中的一维动态规划 算法题解题思路。

上一篇:力扣75------回溯

力扣75------一维动态规划

  • [1 第 N 个泰波那契数](#1 第 N 个泰波那契数)
  • [2 使用最小花费爬楼梯](#2 使用最小花费爬楼梯)
  • [3 打家劫舍](#3 打家劫舍)
  • [4 多米诺和托米诺平铺](#4 多米诺和托米诺平铺)
  • [1- 4解题总结](#1- 4解题总结)

1 第 N 个泰波那契数

题目

cpp 复制代码
泰波那契序列 Tn 定义如下: 

T0 = 0, T1 = 1, T2 = 1, 且在 n >= 0 的条件下 Tn+3 = Tn + Tn+1 + Tn+2

给你整数 n,请返回第 n 个泰波那契数 Tn 的值。

题解:
动态规划。按照公式进行迭代。这题的特点是,如何不使用临时变量而只用3个变量进行迭代。

cpp 复制代码
class Solution {
public:
	int tribonacci(int n) {
        if (n==0) return 0;
        if (n<3) return 1;
		double n0 = 0, n1 = 1, n2 = 1;
		for (int i = 0; i <= n - 3; ++i) {
			n2 = n0 + n1 + n2;
			n1 = n2 - n1 - n0;
			n0 = n2 - n1 - n0;
            /*
			while (n2 > pow(2, 31)) {
				n2 -= pow(2, 31);
			}
			while (n1 > pow(2, 31)) {
				n1 -= pow(2, 31);
			}
            */
		}

		return n2;
	}
};

2 使用最小花费爬楼梯

题目

cpp 复制代码
给你一个整数数组 cost ,其中 cost[i] 是从楼梯第 i 个台阶向上爬需要支付的费用。
一旦你支付此费用,即可选择向上爬一个或者两个台阶。
你可以选择从下标为 0 或下标为 1 的台阶开始爬楼梯。

请你计算并返回达到楼梯顶部的最低花费。

 

题解1:题目是想找到一种方法,使得爬完这个楼梯的费用最少。如果一个人想爬到楼梯上面去,最后就只有2种可能从第cost.size-1 向上走一步到达;从第cost.size-2 向上走2步到达。那么,只要算出分别爬到第cost.size-1和第cost.size-2所需的费用,然后再选择较小的那一个,即为所求结果。

所以可以从第1个台阶开始算,算出一个人爬到这个台阶的费用,然后往上递推计算即可。

cpp 复制代码
class Solution {
public:
	int minCostClimbingStairs(vector<int>& cost) {
		vector<int> result(cost.size(), 0);
		result[0] =cost[0];
		result[1] = cost[1];
		for (int i = 2; i < cost.size(); ++i) {
			result[i] = result[i - 1] > result[i - 2] ? result[i - 2] + cost[i] : result[i - 1] + cost[i];
		}
		return min(result[cost.size() - 1], result[cost.size() - 2]);
	}
};

题解2:

同题解1。但是空间复杂度更低。因为我们只是需要最终结果,所以只需要2个变量 来递推就行,不需要一个vector

cpp 复制代码
class Solution {
public:
	int minCostClimbingStairs(vector<int>& cost) {
		//vector<int> result(cost.size(), 0);
		int result0 = cost[0], result1 = cost[1], tmp = 0;
		for (int i = 2; i < cost.size(); ++i) {
			tmp = result1;
			result1 = result1 > result0 ? result0 + cost[i] : result1 + cost[i];
			result0 = tmp;
		}
		return min(result0, result1);
	}
};

3 打家劫舍

题目

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

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

题解:

动态规划。与题目2类似,只是这次需要3个变量来递推。
问题分析 :直接看这一排房屋的最后两个,如果想要偷最多,最后这两个房子肯定是要偷一个的。可以证明,如果这两个房子都不偷,得到的金额为a,那么a+最后一个房子的钱,肯定是大于a的。
思路分析 :为了确定它是偷最后一个还是偷倒数第二个,还需要知道倒数第三个和倒数第四个要不要偷。所以可以从第一个开始计算,然后递推求解。
解题思路:从第一个房间开始递推,计算偷窃该房子后,金额是多少。设当前房子为i,如果进去偷,则第i-1是不能偷的。那么是2种可能,偷完第i-3后直接偷第i;偷完第i-2后,直接偷第i。具体选择依据偷完它们后哪个金额更大来决定。

cpp 复制代码
class Solution {
public:
	int rob(vector<int>& cost) {
		if (cost.size() < 2) return cost[0];
		int result0 = 0, result1 = cost[0], result2 = cost[1], tmp = 0;
		for (int i = 2; i < cost.size(); ++i) {
			tmp = result2;
			result2 = result1 > result0 ? result1 + cost[i] : result0 + cost[i];
			result0 = result1;
			result1 = tmp;

		}
		return max(result2, result1);
	}
};

4 多米诺和托米诺平铺

题目

cpp 复制代码
有两种形状的瓷砖:一种是 2 x 1 的多米诺形,另一种是形如 "L" 的托米诺形。两种形状都
可以旋转。

给定整数 n ,返回可以平铺 2 x n 的面板的方法的数量。返回对 109 + 7 取模 的值。
平铺指的是每个正方形都必须有瓷砖覆盖。两个平铺不同,当且仅当面板上有四个方向上的相邻
单元中的两个,使得恰好有一个平铺有一个瓷砖占据两个正方形。

题解:

动态规划。对于每一列,如果其左边均铺满瓷砖,右侧未铺,则其总共有4种状态:

一个正方形都没有被覆盖,记为状态0;

只有上方的正方形被覆盖,记为状态1;

只有下方的正方形被覆盖,记为状态2;

上下两个正方形都被覆盖,记为状态3。

通过递推迭代,即可得到结果。

cpp 复制代码
class Solution {
public:
    const long long mod = 1e9 + 7;
    int numTilings(int n) {
        vector<vector<long long>> dp(n + 1, vector<long long>(4));
        dp[0][3] = 1;
        for (int i = 1; i <= n; i++) {
            dp[i][0] = dp[i - 1][3];
            dp[i][1] = (dp[i - 1][0] + dp[i - 1][2]) % mod;
            dp[i][2] = (dp[i - 1][0] + dp[i - 1][1]) % mod;
            dp[i][3] = (dp[i - 1][0] + dp[i - 1][1] + dp[i - 1][2] + dp[i - 1][3]) % mod;
        }
        return dp[n][3];
    }
};

1- 4解题总结

题目特点:一个位置的状态,受到之前位置的影响。

解题方法:从第一个位置开始,计算出它达到每个状态的得分,然后递推下一个位置。

解题重点1:如何将题目转化为状态递推问题。

解题重点2:如何用更少的变量来递推。

相关推荐
醉颜凉42 分钟前
【NOIP提高组】潜伏者
java·c语言·开发语言·c++·算法
hunandede1 小时前
FFmpeg 4.3 音视频-多路H265监控录放C++开发十三.2:avpacket中包含多个 NALU如何解析头部分析
c++·ffmpeg·音视频
lapiii3581 小时前
图论-代码随想录刷题记录[JAVA]
java·数据结构·算法·图论
爱学习的大牛1231 小时前
通过vmware虚拟机安装和调试编译好的 ReactOS
c++·windows内核
Dontla2 小时前
Rust泛型系统类型推导原理(Rust类型推导、泛型类型推导、泛型推导)为什么在某些情况必须手动添加泛型特征约束?(泛型trait约束)
开发语言·算法·rust
Ttang232 小时前
Leetcode:118. 杨辉三角——Java数学法求解
算法·leetcode
喜欢打篮球的普通人2 小时前
rust模式和匹配
java·算法·rust
java小吕布2 小时前
Java中的排序算法:探索与比较
java·后端·算法·排序算法
tumu_C2 小时前
C++模板特化实战:在使用开源库boost::geometry::index::rtree时,用特化来让其支持自己的数据类型
c++·开源