1.最小花费爬楼梯
https://leetcode-cn.com/problems/min-cost-climbing-stairs/
大佬的题解,跟官方解答思路一样(自己加了注释内容)
class Solution {
public:
int minCostClimbingStairs(vector<int>& cost) {
int c1 = cost[0];
int c2 = cost[1];
int N = cost.size();
for (int i = 2; i < N; ++i) {
int c3 = min(c1, c2) + cost[i];
//从i = 2开始,本层的体力加上min(到达第i - 2层花费体力的最小值,到达第i - 1层花费体力的最小值)
c1 = c2;
//c1为到达第i - 1层花费体力的最小值
c2 = c3;
//c2为到达第i层花费体力的最小值
}
return min(c1, c2);
//比较到N - 1和N - 2花费体力的值
}
};
作者:da-li-wang
链接:https://leetcode-cn.com/problems/min-cost-climbing-stairs/solution/c-dong-tai-gui-hua-ti-jie-by-da-li-wang-3/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
这个大佬的题解更好理解
class Solution{
public:
int minCostClimbingStairs(vector<int>& cost) {
int num=cost.size();
for(int i=2;i<num;++i)cost[i]+=min(cost[i-1],cost[i-2]);
return min(cost[num-1],cost[num-2]);
}
};
作者:yzwz
链接:https://leetcode-cn.com/problems/min-cost-climbing-stairs/solution/xiang-dang-yu-yi-ge-fei-bo-na-qi-shu-lie-by-yzwz/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
2.打家劫舍
https://leetcode-cn.com/problems/house-robber/
具体分析看题解第二位大佬(灵魂画手)的题解
思路
标签:动态规划
动态规划方程:dp[n] = MAX( dp[n-1], dp[n-2] + num )
由于不可以在相邻的房屋闯入,所以在当前位置 n 房屋可盗窃的最大值,要么就是 n-1 房屋可盗窃的最大值,要么就是 n-2 房屋可盗窃的最大值加上当前房屋的值,二者之间取最大值
举例来说:1 号房间可盗窃最大值为 33 即为 dp[1]=3,2 号房间可盗窃最大值为 44 即为 dp[2]=4,3 号房间自身的值为 22 即为 num=2,那么 dp[3] = MAX( dp[2], dp[1] + num ) = MAX(4, 3+2) = 5,3 号房间可盗窃最大值为 55
时间复杂度:O(n)O(n),nn 为数组长度
class Solution {
public int rob(int[] nums) {
int len = nums.length;
if(len == 0)
return 0;
int[] dp = new int[len + 1];
dp[0] = 0;
dp[1] = nums[0];
for(int i = 2; i <= len; i++) {
dp[i] = Math.max(dp[i-1], dp[i-2] + nums[i-1]);
}
return dp[len];
}
}
作者:guanpengchn
链接:https://leetcode-cn.com/problems/house-robber/solution/hua-jie-suan-fa-198-da-jia-jie-she-by-guanpengchn/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
我用C++写了一个没过
class Solution {
public:
int rob(vector<int>& nums) {
int len = nums.size();
if(len == 0)
return 0;
if(len == 1)
return nums[0];
//nums[1] = max(nums[0], nums[1]);
for(int i = 2; i < len; i++){
nums[i] = max(nums[i] + nums[i - 2], nums[i - 1]);
}
return max(nums[len - 1], nums[len - 2]);
}
};
是因为注释掉的那句没加上,过不了输入:[2,1,1,2] 正确输出:4
所以还是看看大佬的
3.除数博弈
https://leetcode-cn.com/problems/divisor-game/
(没看题解时,自己只想到爱丽丝令N-x为非三素数时她才能赢,若N = kx, x不等于1,则N - x = (k - 1)x = N’,N’不可能是素数)
题解中的第一位大佬的归纳法用自己的话概括一下(语文课套路)
1.爱丽丝占到 2 赢,占到 1 输;
2.若爱丽丝当前为奇数,奇数的约数只能是奇数或者 1,因此下一个一定是偶数;
3.若爱丽丝当前为偶数, 偶数的约数可以是奇数可以是偶数也可以是 1,因此直接减 1,则下一个是奇数,即鲍勃拿到的一定是奇数,爱丽丝拿到的一定是偶数,一直变小就会到2;
因此,奇则输,偶则赢
class Solution:
def divisorGame(self, N: int) -> bool:
target = [0 for i in range(N+1)]
target[1] = 0 #若爱丽丝抽到1,则爱丽丝输
if N<=1:
return False
else:
target[2] = 1 #若爱丽丝抽到2,则爱丽丝赢
for i in range(3,N+1):
for j in range(1,i//2): #没学过爬虫,意思应该是从1到i的根号(?),j代表x
# 若j是i的余数且target[i-j]为假(0)的话,则代表当前为真(1)
if i%j==0 and target[i-j]==0: #鲍勃拿到i - j,而target[i - j] = 0代表失败,鲍勃失败爱丽丝的target[i] = 1
target[i] = 1
break
return target[N]==1
作者:pandawakaka
链接:https://leetcode-cn.com/problems/divisor-game/solution/python3gui-na-fa-by-pandawakaka/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
4.判断子序列
https://leetcode-cn.com/problems/is-subsequence/
这是博第一个写出来的在动态规划下的题目,虽然不是用动态规划的方法~
class Solution {
public:
bool isSubsequence(string s, string t) {
int len1 = s.length();
long long len2 = t.length();
long long ma = len2;
for(int i = len1 - 1; i >= 0; i--){
bool f = false;
for(int j = ma - 1; j >= 0; j--){
if(s[i] == t[j]){
ma = j;
f = true;
break;
}
}
if(f == false){
return false;
}
}
return true;
}
};