P1164. 模板题_小A点菜
考点
- 01背包
题解
见思路
思路
二维数组实现
经典的01背包问题,每种元素只有一个,且只有选或不选两种状态;题目要求多少种选法能刚好花光m元
可以设dp[i][j]
为前i个元素花了j元,显然有动态转移方程如下:
\[
\underset{\text{前}i-1\text{个元素花}j\text{元}}{\underbrace{dp\left[
i-1 \right] \left[ j \right]
}}+\underset{\text{选第}i\text{个元素,前}i-1\text{个元素应花}j-\cos
t\left[ i \right] \text{元}}{\underbrace{dp\left[ i-1 \right] \left[
j-\cos t\left[ i \right] \right] }}\rightarrow dp\left[ i \right] \left[
j \right]
\]
我们最终要计算的就是dp[n][m]
,即前n个元素花了m元的情况
本题的临界值应该在j == 0
的时候,也就是当预算刚好等于当前物品的价格,只有选自己一种选法
1 |
|
滚动数组实现
由于每次只需要前一个状态,可以去掉第一维的元素计数,只记录开销;但开销的遍历要变成逆序,不能和上述的二维数组一样正序
二维数组是按照不同情况分别记录,正序遍历并不会覆盖旧状态
而浓缩成一维后,若正序遍历,后续状态用到的旧状态都被你覆盖更新完了...
逆序遍历就能保证,每次状态转移方程用到的旧状态是原始的旧状态,并没有被覆盖更新
1 |
|