DP + 贪心 双解 (附贪心证明)
一、状态机模型DP解法
我这里直接贴出闫氏DP分析法的思维导图
具体的状态机模型分析如下图:
一共只$2$有种状态:
1. 当前处于未持股状态0
:
对应可以进行的转换:
0->0 (不买入,继续观望,那么就什么都不发生)
0->1 (买入股票,那么收益就要减去当前市场的股票价格)
2. 当前处于持股状态1
:
对应可以进行的转换:
1->1 (不卖出,继续观望,那么就什么都不发生)
1->0 (卖出股票,那么收益就要加上当前市场的股票价格)
Code:
#include <iostream>
using namespace std;
const int N = 1e5 + 10, INF = 0x3f3f3f3f;
int n;
int w[N];
int f[N][2];
int main() {
scanf("%d", &n);
for (int i = 1; i <= n; ++i) scanf("%d", &w[i]);
f[0][1] = -INF;
for (int i = 1; i <= n; ++i) {
f[i][0] = max(f[i - 1][0], f[i - 1][1] + w[i]);
f[i][1] = max(f[i - 1][1], f[i - 1][0] - w[i]);
}
printf("%d\n", f[n][0]);
return 0;
}
二、贪心解法
纵然,我们可以用DP
搜索出所有的方案数,但是通过观察,我们可以发现本题最优解
方案存在一定的性质。
我先贴出测试样例的折线图形式(绿色
标出下降
,红色
标出上升
):
考虑一种方案,在每次上升
的前一天
购入股票,并在上升后的当天
卖出的方案
if (w[i] > w[i - 1])
res += w[i] - w[i - 1];
接下来证明该贪心
思路得出的方案即是最优解
。
(1)证明贪心解 $\ge$ 最优解:
由于贪心解都是取区间长度为 $1$ 的解,因此假设存在于最优解中的某个区间 $[i, j]$ 的长度 $ > 1$
那么会出现一下三种情况:
对应三种情形:最优解选取的区间最终点位于上方、下方、相等。
对于情形一
:显然 最优解
$ < $ 贪心解
对于情形二
:显然 最优解
$ < $ 贪心解
对于情形三
:毫无疑问,这就是存在于贪心解中的情形,因此 贪心解
$=$ 最优解
得证
(2)证明贪心解 $\le$ 最优解:
这部分无需证明,因为贪心解
即是合法解
,所以他的方案必定大于等于
最优解
Code
#include <iostream>
using namespace std;
const int N = 1e5 + 10, INF = 0x3f3f3f3f;
int n;
int w[N];
int main() {
scanf("%d", &n);
for (int i = 1; i <= n; ++i) scanf("%d", &w[i]);
int res = 0;
for (int i = 2; i <= n + 1; ++i) {
if (w[i] - w[i - 1] > 0) res += w[i] - w[i - 1];
}
printf("%d\n", res);
return 0;
}
(1)三种情况都是最优解=贪心解,怕是没理解最优解的意思。
。。。连反证都不懂的就别来搞笑了。。。
经典第一层笑第五层
以你的智商要你理解文章中的错误真是难为你了,你是对的🤗
Orz
tql
他的意思是假设有与贪心解不同的最优解,很好看出来。这个不算文章的错误,不影响阅读
### 这部分无需证明,因为贪心解即是合法解,所以他的方案必定小于等于最优解
为什么要加上这句话,f[0][1]=-INF;或者,f[0][1]=-2e7;
我不理解。
因为f[0][1]是非法状态 后面的状态不能由f[0][1]转移过来 又因为求的属性是最大值 所以只要初始化为负无穷即可
为什么会想到贪心?
其实做题的时候首先考虑贪心,其次是dp
关于贪心问题或者任何题目,尽可能做出直观化的图形
这题的参数有
三种状态
天数
股票价值
是否买
股票价值参与计算,所以设计另外两个
牛逼
? 哪里 没看出来
感觉这个dp的初始化是面向结果的初始化。。
博主,是否可以简单理解,您的code就是将折线图所有的正数加了起来,所以是最优的?
写得真好!
这个可以
情况也没覆盖全
有个东西叫归纳
笑死,怕是连归纳是什么都没搞明白。
词语:归纳
注音:ㄍㄨㄟ ㄋㄚˋ
词性:动词
基本解释
◎ 归纳 guī nà
(1) [include;sum up]∶归入;加入
无不以归纳共和为福利
(2) [conclude]∶归并;收拢
这是从大量事实中归纳出来的结论
◎ 归纳 guī nà
[induction] [逻辑] 从部分到整体,从特殊到一般,从个别到普遍的推理
——摘自《现代汉语词典》网页版
此处用作释义(1),不知您有何指正(:
(1)证明错的这么明显还有一群人%?
牛蛙牛蛙
牛蛙牛蛙
大佬,证明(2)的最后一句话,方案大于等于最优解。这句话应该是小于等于最优解。
用贪心写出了,但不知道如何证明这种方法的正确性,还是大佬厉害
在下降的前一天卖了,可以啊
Segmentation Fault 是为啥
佩服
膜拜大佬,非常易懂