状态机模型
另类的状态表示方式:
- 状态机: “过程” 而非 “结果”
- 状态压缩DP
"状态机模型"和"01背包问题"的区别:
- 01背包中每个物品选或不选都是独立的, 不受前者约束不对后者产生影响,
- 状态机不一样。
换成01那种状态之间的转化图来看的话, 01背包中0和1的转化不受任何约束,可以说是有向完全图;但是状态机不一样,由于某些条件下的边不存在,于是我们 在计算本次状态之前可能需要了解前一次的状态 ,于是需要状态细分标记
1049 大盗阿福¶
2 状态自动机
阿福是一名经验丰富的大盗。趁着月黑风高,阿福打算今晚洗劫一条街上的店铺。
这条街上一共有 N 家店铺,每家店中都有一些现金。
阿福事先调查得知,只有当他同时洗劫了两家相邻的店铺时,街上的报警系统才会启动,然后警察就会蜂拥而至。
作为一向谨慎作案的大盗,阿福不愿意冒着被警察追捕的风险行窃。
他想知道,在不惊动警察的情况下,他今晚最多可以得到多少现金?
思路1: 动态规划
f[i]
: 前 i 家的最大收益
思路2: 状态机
C++ | |
---|---|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 |
|
1057 股票买卖 IV¶
2 状态自动机
给定一个长度为 N 的数组,数组中的第 i 个数字表示一个给定股票在第 i 天的价格。
设计一个算法来计算你所能获取的最大利润,你最多可以完成 k 笔交易。
注意:你不能同时参与多笔交易(你必须在再次购买前出售掉之前的股票)。一次买入卖出合为一笔交易。
状态机
根据题目中的定义: “手中无货”才表示事先经历了完整的交易
- 状态表示
f[i,j,0]
ANDf[i,j,1]
- 集合: 前 \(i\) 天 进行了 \(j\) 场交易, 且当前手中 无货(0) / 有货(1)
- 属性: max
- 状态计算
f[i, j, 0] = max(f[i-1, j, 0], f[i-1, j, 1] + w[i])
f[i, j, 1] = max(f[i-1, j, 1], f[i-1, j-1, 0] - w[i])
- 注意: \(j-1\) 和 \(j\) 的区别, 这和题目中 "一次买入卖出合为一笔交易" 相关
C++ | |
---|---|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
|
思考: 如何初始化?
- 初始可能值: 赋为0
- 初始不可能值: 赋为
INF
or-INF
- 题目要求max, 则赋为
-INF
- 反之, 赋为
INF
- 题目要求max, 则赋为
1058 股票交易 V¶
3 状态自动机
给定一个长度为 N 的数组,数组中的第 i 个数字表示一个给定股票在第 i 天的价格
设计一个算法计算出最大利润。在满足以下约束条件下,你可以尽可能地完成更多的交易(多次买卖一支股票):
- 你不能同时参与多笔交易(你必须在再次购买前出售掉之前的股票)
- 卖出股票后,你无法在第二天买入股票 (即冷冻期为 1 天)
初始化:
f[0][2] = 0
: 在交易开始前(第0天),你手中没有股票,并且不处于冷冻期f[0][0] = -INF
: 在交易开始前(第0天),你的手中就已经持有一支股票f[0][1] = -INF
: 在交易开始前(第0天),你手中没有股票,但你正处于冷冻期
C++ | |
---|---|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
|