0619刷题
LeetCode 746. 使用最小花费爬楼梯
LeetCode 746. 使用最小花费爬楼梯
class Solution {
public:
int minCostClimbingStairs(vector<int>& cost) {
int n=cost.size();
vector<int> dp(n,0);//到达第N个台阶需要的最低花费
//cost:0~n-1
dp[0] = cost[0];
dp[1] = cost[1];
for(int i=2;i<n;++i)
{
//每当你爬上一个阶梯你都要花费对应的体力值
dp[i]=min(dp[i-1],dp[i-2])+cost[i];
}
return min(dp[n-1],dp[n-2]);// 注意最后一步可以理解为不用花费,所以取倒数第一步,第二步的最少值
}
};
LeetCode 343. 整数拆分
LeetCode 343. 整数拆分
class Solution {
public:
int integerBreak(int n) {
vector<int> dp(n + 1);
dp[2] = 1;
for (int i = 3; i <= n ; i++) {
for (int j = 1; j < i - 1; j++) {
dp[i] = max(dp[i], max((i - j) * j, dp[i - j] * j));
}
}
return dp[n];
}
};
可以想 dp[i]最大乘积是怎么得到的呢?
其实可以从1遍历j,然后有两种渠道得到dp[i].
一个是j * (i - j) 直接相乘。
一个是j * dp[i - j],相当于是拆分(i - j),对这个拆分不理解的话,可以回想dp数组的定义。
那有同学问了,j怎么就不拆分呢?
j是从1开始遍历,拆分j的情况,在遍历j的过程中其实都计算过了。那么从1遍历j,比较(i - j) * j和dp[i - j] * j 取最大的。递推公式:dp[i] = max(dp[i], max((i - j) * j, dp[i - j] * j));
也可以这么理解,j * (i - j) 是单纯的把整数拆分为两个数相乘,而j * dp[i - j]是拆分成两个以及两个以上的个数相乘。
如果定义dp[i - j] * dp[j] 也是默认将一个数强制拆成4份以及4份以上了。
所以递推公式:dp[i] = max({dp[i], (i - j) * j, dp[i - j] * j});