动态规划5部曲
- 确定dp数组(dp table)以及下标的含义
- 确定递推公式
- dp数组如何初始化
- 确定遍历顺序
- 举例推导dp数组
1049.最后一块石头的重量II
leetcode 1049.最后一块石头的重量II
代码随想录
class Solution:
def lastStoneWeightII(self, stones: List[int]) -> int:
stone_sum = sum(stones)
target = stone_sum // 2
dp = [0] * (target + 1)
for stone in stones:
for j in range(target, stone - 1, -1):
# dp[j- stone] + stone # 表示把当前石头放在背包里,剩下的容量取最大价值dp[j-stone]
dp[j] = max(dp[j], dp[j-stone] + stone)
return stone_sum - dp[-1] - dp[-1]
494.目标和
把直接求解转化成了求选出和为target的组合总数。
class Solution:
def findTargetSumWays(self, nums: List[int], target: int) -> int:
nums_sum = sum(nums)
if abs(target) > nums_sum:
return 0
if (nums_sum + target) % 2 == 1:
return 0
target_sum = (nums_sum + target) // 2
dp = [[0]*(target_sum + 1) for _ in range(len(nums) + 1)]
dp[0][0] = 1
for i in range(1, len(nums) + 1):
for j in range(target_sum+1):
dp[i][j] = dp[i-1][j]
if j >= nums[i-1]:
dp[i][j] += dp[i-1][j-nums[i-1]]
# print(dp)
return dp[len(nums)][target_sum]
474.一和零
class Solution:
def findMaxForm(self, strs: List[str], m: int, n: int) -> int:
dp = [[0] * (n+1) for _ in range( m + 1)]
for s in strs:
zero_count_s = s.count("0")
one_count_s = s.count("1")
for i in range(m, zero_count_s - 1, -1):
for j in range(n, one_count_s - 1, -1):
dp[i][j] = max(dp[i][j], dp[i-zero_count_s][j-one_count_s] + 1)
return dp[m][n]