力扣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:如何用更少的变量来递推。

相关推荐
xiaoshiguang33 小时前
LeetCode:222.完全二叉树节点的数量
算法·leetcode
爱吃西瓜的小菜鸡3 小时前
【C语言】判断回文
c语言·学习·算法
别NULL3 小时前
机试题——疯长的草
数据结构·c++·算法
TT哇3 小时前
*【每日一题 提高题】[蓝桥杯 2022 国 A] 选素数
java·算法·蓝桥杯
CYBEREXP20084 小时前
MacOS M3源代码编译Qt6.8.1
c++·qt·macos
yuanbenshidiaos5 小时前
c++------------------函数
开发语言·c++
yuanbenshidiaos5 小时前
C++----------函数的调用机制
java·c++·算法
唐叔在学习5 小时前
【唐叔学算法】第21天:超越比较-计数排序、桶排序与基数排序的Java实践及性能剖析
数据结构·算法·排序算法
ALISHENGYA5 小时前
全国青少年信息学奥林匹克竞赛(信奥赛)备考实战之分支结构(switch语句)
数据结构·算法
tianmu_sama5 小时前
[Effective C++]条款38-39 复合和private继承
开发语言·c++