1 条题解
-
0
题目理解
我们有一个牌堆,从上到下编号为 到 。每次可以:
- 拿走第 张牌(栈顶)
- 或者拿走第 张牌
限制条件:每次拿的牌必须与上一次拿的牌在花色或点数上相同。
目标:最大化拿走的牌的价值总和。
关键观察
1. 操作的影响
当我们拿走一张牌时,牌堆的结构会发生变化:
- 如果拿走第 张牌:牌 成为新的牌 ,牌 成为新的牌 ,依此类推
- 如果拿走第 张牌:牌 位置不变,牌 成为新的牌 ,依此类推
2. 状态表示
由于每次只能拿第 张或第 张牌,牌堆的状态可以用当前的前几张牌来表示。
经过分析,任何时候牌堆的状态可以描述为:
- 当前的第 张牌(原来的某张牌)
- 当前的第 张牌(原来的某张牌)
- 以及从某个位置开始往后的连续牌序列
更具体地说,状态可以定义为 ,表示:
- 牌 是原来的第 张牌
- 牌 是原来的第 张牌
- 牌 及之后的牌是原来的第 张牌开始的连续序列
3. 动态规划状态设计
设 表示:
- 当前牌 是原来的第 张牌
- 当前牌 是原来的第 张牌
- 且上一次拿的牌是某张特定牌(这个信息需要额外维护)
但是这样还不够,我们还需要知道上一次拿的牌的信息来检查合法性。
更好的状态设计: 表示:
- 牌 是原来的第 张牌
- 牌 是原来的第 张牌
- 上一次拿的牌是原来的第 张牌( 表示还没有拿过牌)
在这种状态下能获得的最大价值。
算法思路
1. 状态转移
从状态 出发,有两种选择:
选择1:拿走牌 (原来的第 张牌)
- 条件: 或 或
- 新状态:
- 价值增加:
选择2:拿走牌 (原来的第 张牌)
- 条件: 或 或
- 新状态:
- 价值增加:
2. 初始化
初始状态:,表示牌 是原来的第 张,牌 是原来的第 张,还没有拿过牌。
3. 边界条件
当 或 时,表示没有牌可拿了。
总结
这道题的关键在于:
- 理解操作规则:只能拿第 张或第 张牌,且必须与上一张牌花色或点数相同
- 状态设计:用 表示当前牌堆的前两张牌
- 关键优化:发现 的性质,大幅减少状态数
- 动态规划:正确处理状态转移和边界条件
通过巧妙的状态设计和优化,我们可以在 时间内解决这个看似复杂的问题。
- 1
信息
- ID
- 5225
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 10
- 标签
- 递交数
- 2
- 已通过
- 1
- 上传者