Skip to content

Commit c14be72

Browse files
authored
按照作者算法,添加了Python3 代码对“动态规划博弈”和“最长递增子序列” (labuladong#339)
* Python3 * add Python3 * add Python3 * add Python3 * add Python3
1 parent bcb56c1 commit c14be72

File tree

3 files changed

+109
-1
lines changed

3 files changed

+109
-1
lines changed

动态规划系列/动态规划之博弈问题.md

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -187,8 +187,37 @@ int stoneGame(int[] piles) {
187187

188188
![labuladong](../pictures/labuladong.png)
189189

190+
[Hanmin](https://github.com/Miraclemin/) 提供 Python3 代码:
191+
192+
```python
193+
def stoneGame(self, piles:List[int]) -> int:
194+
n = len(piles)
195+
##初始化dp数组,用三维数组表示
196+
dp = [[[0,0] for _ in range(0,n)] for _ in range(n)]
197+
##填入base case
198+
for i in range(0,n):
199+
dp[i][i][0] = piles[i]
200+
dp[i][i][1] = 0
201+
##斜着遍历数组
202+
for l in range(2,n+1):
203+
for i in range(0,n-l+1):
204+
j = l + i - 1
205+
##先手选择最左边或者最右边的分数
206+
left = piles[i] + dp[i+1][j][1]
207+
right = piles[j] + dp[i][j-1][1]
208+
##套用状态转移方程
209+
if left > right:
210+
dp[i][j][0] = left
211+
dp[i][j][1] = dp[i+1][j][0]
212+
else:
213+
dp[i][j][0] = right
214+
dp[i][j][1] = dp[i][j-1][0]
215+
res = dp[0][n-1]
216+
return res[0] - res[1]
217+
```
218+
190219
[上一篇:动态规划之子序列问题解题模板](../动态规划系列/子序列问题模板.md)
191220

192221
[下一篇:贪心算法之区间调度问题](../动态规划系列/贪心算法之区间调度问题.md)
193222

194-
[目录](../README.md#目录)
223+
[目录](../README.md#目录)

动态规划系列/动态规划设计:最长递增子序列.md

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,54 @@ public int lengthOfLIS(int[] nums) {
186186

187187
![labuladong](../pictures/labuladong.jpg)
188188

189+
[Hanmin](https://github.com/Miraclemin/) 提供 Python3 代码:
190+
191+
**动态规划解法**
192+
193+
``` python
194+
def lengthOfLIS(self, nums: List[int]) -> int:
195+
n = len(nums)
196+
## dp 数组全部初始化为1
197+
dp = [1 for x in range(0,n)]
198+
for i in range(0,n):
199+
for j in range(0,i):
200+
if nums[i] > nums[j]:
201+
dp[i] = max(dp[i],dp[j]+1)
202+
res = 0
203+
for temp in dp:
204+
res = max(temp,res)
205+
return res
206+
```
207+
**二分查找解法**
208+
209+
```python
210+
def lengthOfLIS(self, nums: List[int]) -> int:
211+
top = []
212+
##牌堆初始化为0
213+
piles = 0
214+
for num in nums:
215+
## num为要处理的扑克牌
216+
217+
##二分查找
218+
left, right = 0, piles
219+
while left < right:
220+
mid = (left + right ) // 2
221+
##搜索左侧边界
222+
if top[mid] > num:
223+
right = mid
224+
##搜索右侧边界
225+
elif top[mid] < num:
226+
left = mid + 1
227+
else:
228+
right = mid
229+
if left == piles:
230+
##没有找到合适的堆,新建一堆
231+
piles += 1
232+
##把这张牌放到牌堆顶
233+
top[left] = num
234+
return piles
235+
##牌堆数就是LIS的长度
236+
```
189237

190238
[上一篇:动态规划答疑篇](../动态规划系列/最优子结构.md)
191239

动态规划系列/编辑距离.md

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -322,6 +322,37 @@ public:
322322
}
323323
};
324324
```
325+
326+
[Hanmin](https://github.com/Miraclemin/) 提供 Python3 代码:
327+
328+
```python
329+
def minDistance(self, word1: str, word2: str) -> int:
330+
m, n= len(word1), len(word2)
331+
dp = [[0 for i in range(0,n+1)] for j in range(0,m+1)]
332+
for i in range(1,m+1):
333+
dp[i][0] = i ##base case:当s2为空,s1需要删除所有的字符
334+
for j in range(1,n+1):
335+
dp[0][j] = j ##base case:当s1为空,需要插入所有s2的字符
336+
for i in range(1,m+1):
337+
for j in range(1,n+1):
338+
if word1[i-1] == word2[j-1]: ##当前字符一样
339+
dp[i][j] = dp[i-1][j-1]
340+
else:
341+
dp[i][j] = min(
342+
dp[i-1][j]+1,
343+
##删除s1字符操作,可以理解为我直接把 s1[i]
344+
##这个字符删掉,前移 i,继续跟 j 对比,操作数加一
345+
dp[i][j-1]+1,
346+
##增加s1字符操作,可以理解为我直接在s1[i]插入一个和s2[j]一样的字符
347+
##s2[j]被匹配,那么前移 j,继续跟 i 对比,操作数加一
348+
dp[i-1][j-1]+1
349+
##修改s1字符操作,可以理解为我直接替换s1[i]为s2[j]一样的字符
350+
##s2[j]被匹配,那么前移 i,j,操作数加一
351+
)
352+
353+
return dp[m][n] ##返回s1,s2最小的编辑距离
354+
```
355+
325356
[上一篇:动态规划设计:最长递增子序列](../动态规划系列/动态规划设计:最长递增子序列.md)
326357

327358
[下一篇:经典动态规划问题:高楼扔鸡蛋](../动态规划系列/高楼扔鸡蛋问题.md)

0 commit comments

Comments
 (0)