ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

【LeetCode】动态规划(下篇共39题)

2019-02-09 18:39:32  阅读:310  来源: 互联网

标签:unhold 39 下篇 int max soup hold LeetCode dp


【600】 Non-negative Integers without Consecutive Ones

【629】 K Inverse Pairs Array

【638】 Shopping Offers

【639】 Decode Ways II

【646】 Maximum Length of Pair Chain

【647】 Palindromic Substrings

【650】 2 Keys Keyboard

【651】 4 Keys Keyboard

【656】 Coin Path

【664】 Strange Printer

【673】 Number of Longest Increasing Subsequence 

【688】 Knight Probability in Chessboard

【689】 Maximum Sum of 3 Non-Overlapping Subarrays

【691】 Stickers to Spell Word

【698】 Partition to K Equal Sum Subsets 

 

【712】 Minimum ASCII Delete Sum for Two Strings (2018年12月21日,算法群)

给了两个字符串 s1 和 s2,要从 s1 和 s2 中删除一些字符使得这两个字符串相等。求最小的删除字符的 ACSII 的和。

题解:字符串的编辑距离的变种。dp[i][j] 表示从 s1[0..i-1] 到 s2[0..j-1] 这两个字符串相等所求的最小和。转移方程为: if (s1[i-1] == s2[j-1]) {dp[i][j] = dp[i-1][j-1]}, else {dp[i][j] = min(dp[i-1][j] + (int)s1[i-1], dp[i][j-1] + (int)s2[j-1])}

 1 class Solution {
 2 public:
 3     int minimumDeleteSum(string s1, string s2) {
 4         const int n1 = s1.size(), n2 = s2.size();
 5         vector<vector<int>> dp(n1 + 1, vector<int>(n2 + 1, INT_MAX));
 6         dp[0][0] = 0;
 7         for (int i = 1; i <= n1; ++i) {
 8             dp[i][0] = dp[i-1][0] + (int)s1[i-1];
 9         }
10         for (int j = 1; j <= n2; ++j) {
11             dp[0][j] = dp[0][j-1] + (int)s2[j-1];
12         }        
13         for (int i = 1; i <= n1; ++i) {
14             for (int j = 1; j <= n2; ++j) {
15                 if (s1[i-1] == s2[j-1]) {
16                     //dp[i][j] = min(dp[i][j], min(dp[i-1][j] + (int)s1[i-1], dp[i][j-1] + (int)s2[j-1]));
17                     dp[i][j] = min(dp[i][j], dp[i-1][j-1]);
18                 } else {
19                     dp[i][j] = min(dp[i][j], min(dp[i-1][j] + (int)s1[i-1], dp[i][j-1] + (int)s2[j-1]));
20                 }
21             }
22         }
23         return dp[n1][n2];
24     }
25 };
View Code

 

【714】 Best Time to Buy and Sell Stock with Transaction Fee (算法群 2018年10月22日题目)

还是股票买卖的相关问题,给了一个股票价格的数组,prices[i] 代表第 i 天的股票价格,每次卖出要交手续费,问最后的max profit 是多少。

题解:https://leetcode.com/problems/best-time-to-buy-and-sell-stock-with-transaction-fee/discuss/108892/Java-DP-solution-O(n)-to-O(1)-space

这题可以用滚动数组(两个变量优化成O(1)的空间复杂度),但是优化后的不好理解,而且这种优化也不算什么高端技巧。所以我们这里先讨论下这题 dp 的本质。

我们第 i 天要么持有股票,要么不持有股票。 我们用 hold[i] 表示第 i 天持有股票的 max profit, unhold[i] 表示第 i 天不持有股票的 max profit。

那么转移方程可以这么理解: 我们在第 i 天有两种情况,要么我们持有股票,要么我们不持有股票。

1. 第 i 天持有股票的情况下, hold[i] = max(hold[i-1], unhold[i-1] - prices[i])  //意思是说我们要么第 i-1 天就持有股票, 第 i 天啥也不干; 要么我们在第 i 天买了股票

2.第 i 天不持有股票的情况下, unhold[i] = max(unhold[i-1], hold[i-1] + prices[i] - fee) //意思是说我们 第 i-1 天就不持有股票了,第 i 天啥也不干; 要们我们在第 i 天卖了股票

现在的时间复杂度是O(N), 空间复杂度是O(1)。可以用两个变量优化两个数组。

 1 class Solution {
 2 public:
 3     //hold[i] represents max profit of holding stock until day i
 4     //nothold[i] represents max profit of not holding stock until day i
 5     //transaction function: for each day i, we have 2 situations.
 6     //1. hold stock in day i (you can either do nothing in day i or buy stock int day i)
 7     // hold[i] = max(hold[i-1], nothold[i-1]-price[i])
 8     //2. not hold stock in day i (you can either do nothing in day i or sell stock in day i)
 9     // nothold[i] = max(nothold[i-1], hold[i-1] + price[i] - fee)
10     
11     int maxProfit(vector<int>& prices, int fee) {
12         const int n = prices.size();
13         if (n <= 1) { return 0; }
14         vector<int> hold(n, 0), unhold(n, 0);
15         hold[0] = -prices[0], unhold[0] = 0;
16         for (int i = 1; i < n; ++i) {
17             hold[i] = max(hold[i-1], unhold[i-1] - prices[i]);
18             unhold[i] = max(unhold[i-1], hold[i-1] + prices[i] - fee);
19         }
20         return unhold[n-1];
21     }
22 };
View Code

【718】 Maximum Length of Repeated Subarray

【727】 Minimum Window Subsequence 

【730】 Count Different Palindromic Subsequences

【740】 Delete and Earn

【741】 Cherry Pickup (2019年1月12日,算法群)

今天心情很差,抄的答案==,有点upset

【746】 Min Cost Climbing Stairs

【750】 Number Of Corner Rectangles

【764】 Largest Plus Sign

 

【787】 Cheapest Flights Within K Stops(2019年2月9日)

给了一个有向图,边上有权重,问从 src 到 dst 最多经过 K 个站的最少花费。

题解:dp[k][v] 表示从 src 开始到 v 经过 k 个站的最小花费。dp[k][v] = min(dp[k][v], dp[k-1][u] + cost[u][v])。时间复杂度是 O(K*n*n)

 1 //time complexity: O(k*n*n)
 2 class Solution {
 3 public:
 4     int findCheapestPrice(int n, vector<vector<int>>& flights, int src, int dst, int K) {
 5         vector<vector<int>> dp(K + 1, vector<int>(n, INT_MAX));
 6         vector<vector<int>> cost(n, vector<int>(n, INT_MAX));
 7         //init
 8         int ret = INT_MAX;
 9         for (auto& f : flights) {
10             int u = f[0], v = f[1], w = f[2];
11             if (u == src) { 
12                 dp[0][v] = w; 
13                 if (v == dst) {ret = w;}
14             }
15             cost[u][v] = w;
16         }
17         for (int k = 1; k <= K; ++k) {
18             for (int d = 0; d < n; ++d) {
19                 for (int u = 0; u < n; ++u) {
20                     if (cost[u][d] == INT_MAX || dp[k-1][u] == INT_MAX) {continue;}
21                     dp[k][d] = min(dp[k][d], dp[k-1][u] + cost[u][d]);
22                 }
23                 if (d == dst) { ret = min(ret, dp[k][d]); }
24             }
25         }
26         if (ret == INT_MAX) { ret = -1; }
27         return ret;
28     }
29 };
View Code

 

【790】 Domino and Tromino Tiling

【801】 Minimum Swaps To Make Sequences Increasing 

 

【808】 Soup Servings (2019年1月4日,算法群,第一次做,需要复习)

给了 A,B 两种 soup,一开始都有 N ml。有如下四种选择,每种选择的概率都是 25%。

  1. Serve 100 ml of soup A and 0 ml of soup B
  2. Serve 75 ml of soup A and 25 ml of soup B
  3. Serve 50 ml of soup A and 50 ml of soup B
  4. Serve 25 ml of soup A and 75 ml of soup B

如果在配比中有一种soup的剂量不够调一份的,就用剩下所有的调一份。返回 soup A 先空的概率 加上 soup A, B一起空的概率。

题解:我们用 25ml 算一个 serving,先计算A, B每种 soup 的serving。我们用一个记忆化数组来记录算过的概率。

f[a][b] = 0.25 * (f[a-4][b] + f[a-3][b-1] + f[a-2][b-2] + f[a-1][b-3])

 1 class Solution {
 2 public:
 3     double soupServings(int N) {
 4         const int serving = N / 25 + (N % 25 >= 1 ? 1 : 0);
 5         if (serving >= 500) {
 6             return 1.0;
 7         }
 8         return helper(serving, serving);
 9     }
10     double helper(int a, int b) {
11         if (a == 0 && b == 0) {
12             return 0.5;
13         } else if (a == 0) {
14             return 1.0;
15         } else if (b == 0) {
16             return 0.0;
17         }
18         if (memo.find(a) != memo.end() && memo[a].find(b) != memo[a].end()) {
19             return memo[a][b];
20         }
21         double ret = 0.0;
22         ret = 0.25 * (helper(max(a-4, 0), b) + helper(max(a-3, 0), max(b-1, 0)) + helper(max(a-2, 0), max(b-2, 0)) + helper(max(a-1, 0), max(b-3, 0)));
23         memo[a][b] = ret;
24         return ret;
25     }
26     unordered_map<int, unordered_map<int, double>> memo;
27 };
View Code

 

【813】 Largest Sum of Averages 

【818】 Race Car 

【837】 New 21 Game 

【838】 Push Dominoes

【847】 Shortest Path Visiting All Nodes 

【871】 Minimum Number of Refueling Stops

【873】 Length of Longest Fibonacci Subsequence

【877】 Stone Game

【879】 Profitable Schemes

【887】 Super Egg Drop

 

标签:unhold,39,下篇,int,max,soup,hold,LeetCode,dp
来源: https://www.cnblogs.com/zhangwanying/p/9567473.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有