编程集训第7天:DP实战–0-1背包问题实现(自我实现)及Leetcode(132)Palindrome Partitioning II
编程题目
1.背包问题
概述: 有n种物品与承重为m的背包。每种物品只有一件,每个物品都有对应的重量weight[i]与价值value[i],求解如何装包使得价值最大。
思路: 遇到这种问题,最简单也是最耗费时间的解决方法是遍历,将所有情况都计算出来,再从结果中找最优解,我们今天介绍的动态规划就是在这个基础上演变而来的。我们都知道,遍历之所以耗费时间,是由于它的计算量巨大,我们通过观察它的计算过程可以发现,其实它的很多计算操作计算的都是之前计算过的量。那我们如果把这些已经计算过的量储存起来,当我们需要的适合直接提取它的结果,就起到了减少计算量的效果,我们的动态规划使用的就是这种思想。
问题描述: 有3种物品,他们的重量和价格分别是10, 20, 30 kg和$60, $100, $120。
分析可以得到如下的递推公式:
python:
import numpy as np
def solve(vlist,wlist,totalWeight,totalLength):
resArr = np.zeros((totalLength+1,totalWeight+1),dtype=np.int32)
for i in range(1,totalLength+1):
for j in range(1,totalWeight+1):
if wlist[i] <= j:
resArr[i,j] = max(resArr[i-1,j-wlist[i]]+vlist[i],resArr[i-1,j])
else:
resArr[i,j] = resArr[i-1,j]
return resArr[-1,-1]
if __name__ == '__main__':
v = [0,60,100,120]
w = [0,10,20,30]
weight = 50
n = 3
result = solve(v,w,weight,n)
print(result)
2.Leetcode(132) Palindrome Partitioning II
题目描述:
给定一个字符串 s,将 s 分割成一些子串,使每个子串都是回文串。
返回符合要求的最少分割次数。
思路: dp[i]是s[0:i]前i个字符所返回的最小分割次数。采用了动态规划思想,也就是借用之前算过的dp[j],如果s[j:i]是回文串,则可以进行以下分割:在s[j-1]与s[j]之间进行分割,则dp[i]=dp[j]+1;同时在前i个数字进行组合遍历的情况下取遍历结果的最小值,即dp[i] = min(dp[i],dp[j]+1)。
python:
class Solution(object):
def minCut(self, s):
"""
:type s: str
:rtype: int
"""
n = len(s)
dp = [(i - 1) for i in range(n + 1)] #初始化dp=[-1,0,...]
for i in range(1, n + 1):
for j in range(i):
tmp = s[j:i]
if tmp == tmp[::-1]:
dp[i] = min(dp[i], dp[j] + 1)
return dp[n]