给你一个字符串 s
和一个字符串列表 wordDict
作为字典。请你判断是否可以利用字典中出现的单词拼接出 s
。
注意:不要求字典中出现的单词全部都使用,并且字典中的单词可以重复使用。
示例 1:
输入: s = "leetcode", wordDict = ["leet", "code"] 输出: true 解释: 返回 true 因为 "leetcode" 可以由 "leet" 和 "code" 拼接成。
示例 2:
输入: s = "applepenapple", wordDict = ["apple", "pen"] 输出: true 解释: 返回 true 因为 "applepenapple" 可以由 "apple" "pen" "apple" 拼接成。 注意,你可以重复使用字典中的单词。
示例 3:
输入: s = "catsandog", wordDict = ["cats", "dog", "sand", "and", "cat"] 输出: false
提示:
1 <= s.length <= 300
1 <= wordDict.length <= 1000
1 <= wordDict[i].length <= 20
s
和 wordDict[i]
仅由小写英文字母组成wordDict
中的所有字符串 互不相同139.单词拆分
(1)解题思路
# 利用单词(物体)构成字典(背包)
# 数组:字典 i 之前的所有部分是否能由单词构成 dp[i]
# 初始化:为在后续处理中便于被覆盖,初始化其为 False
dp = [False] * (len(s) + 1)
# 初始化空格位置为 True ,不会影响后续元素的判断
dp[0] = True
# 递推关系:若当前物体之前的位置为true,且当前位置的单词存在于字典中
dp[j] = dp[j] or (dp[j-len(word)] and word == s[j-len(word):j])
(2)过程想法
总体的思路很好理解,但需构思递推关系怎么写
class Solution:
def wordBreak(self, s: str, wordDict: List[str]) -> bool:
# 利用单词(物体)构成字典(背包)
# 数组:字典 i 之前的所有部分是否能由单词构成 dp[i]
# 初始化:为在后续处理中便于被覆盖,初始化其为 False
dp = [False] * (len(s) + 1)
# 初始化空格位置为 True ,不会影响后续元素的判断
dp[0] = True
# 递推关系:若当前物体之前的位置为true,且当前位置的单词存在于字典中
for j in range(1,len(s)+1) : # 遍历背包
for word in wordDict: # 遍历物体
if j >= len(word):
dp[j] = dp[j] or (dp[j-len(word)] and word == s[j-len(word):j])
return dp[len(s)]
你是一名宇航员,即将前往一个遥远的行星。在这个行星上,有许多不同类型的矿石资源,每种矿石都有不同的重要性和价值。你需要选择哪些矿石带回地球,但你的宇航舱有一定的容量限制。
给定一个宇航舱,最大容量为 C。现在有 N 种不同类型的矿石,每种矿石有一个重量 w[i],一个价值 v[i],以及最多 k[i] 个可用。不同类型的矿石在地球上的市场价值不同。你需要计算如何在不超过宇航舱容量的情况下,最大化你所能获取的总价值。
输入共包括四行,第一行包含两个整数 C 和 N,分别表示宇航舱的容量和矿石的种类数量。
接下来的三行,每行包含 N 个正整数。具体如下:
第二行包含 N 个整数,表示 N 种矿石的重量。
第三行包含 N 个整数,表示 N 种矿石的价格。
第四行包含 N 个整数,表示 N 种矿石的可用数量上限。
输出一个整数,代表获取的最大价值。
10 3
1 3 4
15 20 30
2 3 2
90
数据范围:
1 <= C <= 10000;
1 <= N <= 10000;
1 <= w[i], v[i], k[i] <= 10000;
56.携带矿石资源
(1)解题思路
# 用矿石(物品)装满宇航仓(背包),因为每种物体的数量是有限但不都为1 ,属于多重背包问题,处理思路:在 0-1 背包的基础上,加上数量判断。
# 数组:宇航仓容量为 j 时,其最大能获取的价值为 dp[j]
# 初始化:求最大,且没有负值,初始化为 0,便于覆盖
dp = [0] * (bagWeight + 1)
# 递推关系:dp[j] = max(dp[j], dp[j-weight[i]]+value[i])
# 01背包问题——先遍历物体,再遍历背包容量
(2)过程想法
卡哥说面试大多考 0-1 背包和完全背包问题,这类多重背包问题参考看看即可
def read_input():
# 创建四个空列表,用于存储四个数字列表
values = []
weights = []
nums = []
for i in range(4):
# 使用input函数获取用户输入
line = input("".format(i+1))
# 根据行号存储到相应的列表中
if i == 0:
C, N = map(int, line.strip().split())
elif i == 1:
weights = list(map(int, line.strip().split()))
elif i == 2:
values = list(map(int, line.strip().split()))
elif i == 3:
nums = list(map(int, line.strip().split()))
return C, N, weights, values, nums
def maxValue(bagWeight,N,weights,values,nums):
# 用矿石(物品)装满宇航仓(背包)
# 数组:宇航仓容量为 j 时,其最大能获取的价值为 dp[j]
# 初始化:求最大,且没有负值,初始化为 0,便于覆盖
dp = [0] * (bagWeight + 1)
dp[0] = 0
# 递推关系:dp[j] = max(dp[j], dp[j-weight[i]]+value[i])
# 01背包问题——先遍历物体,再遍历背包容量
for i in range(N): # 遍历物体
for j in range(bagWeight,weights[i]-1,-1): # 倒序遍历背包容量
for k in range(1,nums[i]+1): # 遍历物体数量
if j - k * weights[i] >= 0:
# 乘以 k 是因为一维滚动数组的潜在含义:依次遍历物体的种类
dp[j] = max(dp[j], dp[j- k * weights[i]]+ k * values[i])
else:
break
return dp[bagWeight]
if __name__ == "__main__":
# 调用函数并获取输入的数字列表
C, N, weights, values, nums = read_input()
print(maxValue(C,N,weights,values,nums))