| |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
-> 数据结构与算法 -> 动态规划之如何将问题抽象转化为0-1背包问题(详解利用动态规划求方案数) -> 正文阅读 |
|
[数据结构与算法]动态规划之如何将问题抽象转化为0-1背包问题(详解利用动态规划求方案数) |
??前面的话?? 本篇文章介绍如何对问题抽象转化成0-1背包问题求解和运用0-1背包求方案数。
??如何将问题抽象为0-1背包??通过一道题来说明如何将问题抽象为0-1背包问题。 🔐最后一块石头的重量 II有一堆石头,用整数数组 每一回合,从中选出任意两块石头,然后将它们一起粉碎。假设石头的重量分别为
最后,最多只会剩下一块 石头。返回此石头 最小的可能重量 。如果没有石头剩下,就返回 示例 1:
示例 2:
提示:
💡解题思路分析: 题目告诉了我们每个石头的重量,两块石头粉碎后,只会剩下正差值的重量的石头,该石头可能会再次参与粉碎操作,题目要求的是一堆石头经过很多次两两粉碎后,剩余最后一块的 最小 重量。 两块石头进行“粉碎时”可以将重量较大的石头分为一组,称为大堆,粉碎时,相当于给大堆的石块赋予 如果考虑粉碎石头重新放回的情况,其实本质上就是将原来分好的石块进行重组,比如假如有两个石块重量分别为 综上分析,石头经历多次粉碎,改变的仅仅只是分布在哪一个组里面而已,只不过组的分界条件,由两块石头哪块更重变为最终石头被赋予的权重是 那么此时,问题不知不觉就转化为:给你一堆石头的重量,每个石头只能选择一次,每次你可以加这个石头的重量,也可以减石头的重量,求不小于0的最小重量。 那这不就和之前做的[分割等和子集]那道题很像吗?我们把被赋予 不妨设 不难推出 最后再拿这个最大和的两倍减去 状态定义: d p [ i ] [ j ] dp[i][j] dp[i][j]表示从前 i i i个元素中选择,不超过 j j j的最大元素和,其中每个元素只能选择一次。 确定初始状态: 我们考虑当 i = 0 i=0 i=0时表示没有任何元素可以选择,所以不论 j j j为何值时, d p [ i ] [ j ] = 0 dp[i][j]=0 dp[i][j]=0。 状态转移方程: 我们考虑选择第 i i i个元素,重量为 s t o n e s [ i ? 1 ] stones[i-1] stones[i?1],如果我们不选择该元素, d p [ i ] [ j ] = d p [ i ? 1 ] [ j ] dp[i][j]=dp[i-1][j] dp[i][j]=dp[i?1][j],如果我们选择该元素,前提必须满足 j > = s t o n e s [ i ? 1 ] j>=stones[i-1] j>=stones[i?1],此时 d p [ i ] [ j ] = d p [ i ? 1 ] [ j ? s t o n e s [ i ? 1 ] ] dp[i][j]=dp[i-1][j-stones[i-1]] dp[i][j]=dp[i?1][j?stones[i?1]],由于是求最大值,所以选择两者更大的那一个。 所以最终状态转移方程为 d p [ i ] [ j ] = m a x ( d p [ i ? 1 ] [ j ] , d p [ i ? 1 ] [ j ? s t o n e s [ i ? 1 ] ] ) dp[i][j]=max(dp[i-1][j], dp[i-1][j-stones[i-1]]) dp[i][j]=max(dp[i?1][j],dp[i?1][j?stones[i?1]])。 实现代码:
时间复杂度:
O
(
n
?
s
u
m
/
2
)
O(n*sum/2)
O(n?sum/2) 滚动数组优化:
时间复杂度:
O
(
n
?
s
u
m
/
2
)
O(n*sum/2)
O(n?sum/2)
时间复杂度:
O
(
n
?
(
s
u
m
/
2
?
s
t
o
n
e
s
[
i
?
1
]
)
)
O(n*(sum/2-stones[i-1]))
O(n?(sum/2?stones[i?1])) 📝练习:目标和题目: 494. 目标和 给你一个整数数组 向数组中的每个整数前添加
返回可以通过上述方法构造的、运算结果等于 示例 1:
示例 2:
提示:
🔑习题解答分析: 这道题就是给数组 我们先来考虑计算式的极限边界,不妨设数组 然后我们来考虑定义状态的定义。 状态定义: 我们知道计算式的范围是 [ ? s , s ] [-s,s] [?s,s]区间内的整数,由于数组的下标不能为负值,所以我们定义动态规划数组时需向右偏移 s s s位,即 d p [ i ] [ 0 ] dp[i][0] dp[i][0]中的目标值 j = ? s j=-s j=?s,那么 d p [ i ] [ s ] dp[i][s] dp[i][s]中的目标值为 j = 0 j=0 j=0,不难推出实际下标值为 j + s j+s j+s。计算式的范围有 2 s + 1 2s+1 2s+1个整数,所以需要申请动态规划数组的列数为 2 ? s + 1 2*s+1 2?s+1。 确定初始状态: 当没有元素可以加权时,它的结果只能是 状态转移方程: 所谓对数组元素加权 状态转移方程为 d p [ i ] [ j ] = d p [ i ? 1 ] [ j + s ? t ] + d [ i ? 1 ] [ j + s + t ] dp[i][j]=dp[i-1][j+s-t]+d[i-1][j+s+t] dp[i][j]=dp[i?1][j+s?t]+d[i?1][j+s+t]。 实现代码:
时间复杂度:
O
(
2
?
l
e
n
?
s
)
O(2*len*s)
O(2?len?s) 滚动数组优化:
时间复杂度:
O
(
2
?
l
e
n
?
s
)
O(2*len*s)
O(2?len?s) 由于当行的数据更新,与前一行的前后都有关系,因此对于这道题不适合一维优化,但是我们定义状态时,考虑了 [ ? s , s ] [-s,s] [?s,s]区间内所有的值,这就包含了目标情况不可能取到的一些状态值。下面我们根据这一点来进行优化。 ?优化方案比如当题目给的
t
a
r
g
e
t
target
target不为
s
s
s和
?
s
-s
?s时,那这两个值就是无效的状态值。为了规避掉这些无效的状态值,我们重新开始再来分析分析,我们将赋予
+
+
+权重的分为一组叫做【正权重部分】,反之将赋予
?
-
?的分为一组叫做【负权重部分】,不妨设数组的绝对值元素和为
s
s
s,【负权重部分】的绝对值元素和为
m
m
m,则【正权重部分】的元素和为
s
?
m
s-m
s?m,我们可以做以下的推导。 根据推断,只要凑出 m m m,那么【正权重部分】也就确定了,于是问题就变成仅使用 + + +,从数组中凑出 m m m的方案数,但是前提是 s ? t a r g e t s-target s?target能够被 2 2 2整除,如果不能被 2 2 2整除,表示无法凑出 t a r g e t target target,方案数直接为 0 0 0,所以需要在 s ? t a r g e t s-target s?target为偶数的情况下,才会存在有效的方案。 在原问题中的 m m m会被赋予负权重,剩下的元素会被赋予正权重,由以上分析我们可以开始定义状态。 状态定义: 实现代码:
时间复杂度:
O
(
l
e
n
?
(
s
?
t
a
r
g
e
t
)
)
O(len*(s-target))
O(len?(s?target)) 滚动数组优化:
时间复杂度:
O
(
l
e
n
?
(
s
?
t
a
r
g
e
t
)
)
O(len*(s-target))
O(len?(s?target))
时间复杂度:
O
(
l
e
n
?
(
s
?
t
a
r
g
e
t
?
n
u
m
s
[
i
?
1
]
)
)
O(len*(s-target-nums[i-1]))
O(len?(s?target?nums[i?1])) 🌱参考资料: |
|
|
上一篇文章 下一篇文章 查看所有文章 |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 | -2024/11/26 4:55:10- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |