总结

1. 更新动规矩阵时, 不要 push 更新, 要用 pull更新. push 更新容易让逻辑出问题, 自己卡了很久, 改用 pull 就变得很顺利了

2. acm 题, 空间至多是百万, 再网上就会超的

3. 曾做过一道题, 和这个类似. 好像是背包问题的一个变形把, 核心都是降维. 降维的过程又是一道动规题目

题目描述:

给定一个大小为n的数组,数组的元素a[i]代表第i天的股票价格
设计一个算法,计算在最多允许买卖k次(一买一卖记为一次)的条件下的最大收益
需要注意的是,你不能同时拥有两份股票。也就是说在下次买入前,你必须把手头上原有的股票先卖掉

思路

1. 假设 dp[i][j] 表示前 i 天, 最多允许买卖 j 次的最大收益, 那么 dp[i][j] = max{(dp[m][j-1] + price[i]-price[m+1]),price[i]-price[0]}  (0<=m<i) 需要遍历 i, j, m 时间复杂度为o (n*n*k), 提交代码超时

2. 若是把 dp[i][j] 拆开来写, 那么

dp[i][j] = max {

0 - price[0] + price[i],

dp[0][j-1] - price[1] + price[i],

dp[1][j-1] - price[2] + price[i],

...

dp[i-1][j-1] - price[i] + price[i]

}

在求解 dp[i][j] 之前, dp[i-1][j-1] 已经被求出, 所以可以存储 max(dp[m][j-1]-price[m+1]), 在 dp[i][j] 需求时直接调用, 这样的话, 时间复杂度下降一维, o(n*k)

总体的思路就是上面了

3. 假设 dp2[n-1][k-1] 为所求的最终结果, 假设

dp1[i][j] = max {

0 - price[0],

dp2[0][j-1] - price[1],

dp2[1][j-1] - price[2],

...

dp2[i-1][j-1] - price[i],

}

那么 dp2[i][j] = dp1[i][j] + price[i]   ---------------- a

max(dp1[i][j], dp2[i][j-1]-price[i+1])  ==> dp1[i+1][j]

所以 dp1[i][j] = max(dp1[i-1][j], dp2[i-1][j-1]-price[i]) --------------------b

a, b 是题目的状态转移方程, 剩下的也是最难的就是初始化了

4. 首先看 dp1 的, dp1[i][j] = max(dp1[i-1][j], dp2[i-1][j-1]-price[i]). 想象一个二维矩阵, dp1[i][j] 是由其上面和左上两个格子组合, 那么 dp1[i][j] 的第一行就无法通过递推的来, 只能初始化, 手动生成. 同样的道理, dp1 第一列也无法递推而得. 不过好在 dp2[0][i] 都等于 0, dp2[i][0] 相当于 [0~i] 的最大利润, 可以递推求出.

那么, 我们看第二行需要些什么.

dp1[1][1] = max(0-price[0], dp2[0][0]-price[1]) = max(dp1[0][1], dp2[0][0]-price[1])

dp1[1][2] = max(0-price[0], dp2[0][1]-price[1]) = max(dp1[0][2], dp2[0][1]-price[1])

...

dp1[1][i] = max(0-price[0],  dp2[0][i-1] -price[1])= max(dp1[0][i-1], dp2[0][i]-price[1])

所以, dp1[0][i] = 0-price[0] 即可, dp1[i][0] 不需要初始化, 因为 dp2[i][0] 可以直接求出

代码

未能通过九度测试, 第 4 个案例无法通过

#include <iostream>
#include <stdio.h>
using namespace std; int dp1[][];
int dp2[][];
int prices[]; void init(int n, int k) {
for(int i = ; i < k; i ++) {// init first line
dp1[][i] = -prices[];
dp2[][i] = ;
} int global = , local = ;
for(int i = ; i < n; i ++) {// init first column
local = max(, prices[i]-prices[i-]+local);
global = max(global, local);
dp2[i][] = global;
}
} int dodp(int n, int k) {
for(int i = ; i < n; i ++) {
for(int j = ; j < k; j ++) {
dp1[i][j] = max(dp1[i-][j], dp2[i-][j-]-prices[i]);
dp2[i][j] = dp1[i][j] + prices[i];
}
}
return dp2[n-][k-];
} int main() {
freopen("testcase.txt", "r", stdin);
int n,k;
while(scanf("%d%d", &n, &k) != EOF) {
for(int i = ; i < n; i ++)
scanf("%d", prices+i); init(n, k);
int res = dodp(n, k);
cout << res << endl;
}
return ;
}

九度 1537:买卖股票(区间DP)的更多相关文章

  1. 九度OJ 1552座位问题(dp)

    刚开始写的一维数组,但是由于后面的数字较大,要对它取模,所以用一维数组进行减法运算,结果就不对了.所以还是得用二维数组,用dp[n][0]来表示第n位为男生总的方法个数,dp[n][1]表示第n位为女 ...

  2. 九度 1547 出入栈(递推DP)

    题目描述: 给定一个初始为空的栈,和n个操作组成的操作序列,每个操作只可能是出栈或者入栈.要求在操作序列的执行过程中不会出现非法的操作,即不会在空栈时执行出栈操作,同时保证当操作序列完成后,栈恰好为一 ...

  3. Leetcode之动态规划(DP)专题-121. 买卖股票的最佳时机(Best Time to Buy and Sell Stock)

    Leetcode之动态规划(DP)专题-121. 买卖股票的最佳时机(Best Time to Buy and Sell Stock) 股票问题: 121. 买卖股票的最佳时机 122. 买卖股票的最 ...

  4. Leetcode之动态规划(DP)专题-122. 买卖股票的最佳时机 II(Best Time to Buy and Sell Stock II)

    Leetcode之动态规划(DP)专题-122. 买卖股票的最佳时机 II(Best Time to Buy and Sell Stock II) 股票问题: 121. 买卖股票的最佳时机 122. ...

  5. Leetcode之动态规划(DP)专题-123. 买卖股票的最佳时机 III(Best Time to Buy and Sell Stock III)

    Leetcode之动态规划(DP)专题-123. 买卖股票的最佳时机 III(Best Time to Buy and Sell Stock III) 股票问题: 121. 买卖股票的最佳时机 122 ...

  6. Leetcode之动态规划(DP)专题-188. 买卖股票的最佳时机 IV(Best Time to Buy and Sell Stock IV)

    Leetcode之动态规划(DP)专题-188. 买卖股票的最佳时机 IV(Best Time to Buy and Sell Stock IV) 股票问题: 121. 买卖股票的最佳时机 122. ...

  7. Leetcode之动态规划(DP)专题-309. 最佳买卖股票时机含冷冻期(Best Time to Buy and Sell Stock with Cooldown)

    Leetcode之动态规划(DP)专题-309. 最佳买卖股票时机含冷冻期(Best Time to Buy and Sell Stock with Cooldown) 股票问题: 121. 买卖股票 ...

  8. Leetcode之动态规划(DP)专题-714. 买卖股票的最佳时机含手续费(Best Time to Buy and Sell Stock with Transaction Fee)

    Leetcode之动态规划(DP)专题-714. 买卖股票的最佳时机含手续费(Best Time to Buy and Sell Stock with Transaction Fee) 股票问题: 1 ...

  9. 九度OJ 1337:寻找最长合法括号序列 (DP)

    时间限制:1 秒 内存限制:32 兆 特殊判题:否 提交:839 解决:179 题目描述: 给你一个长度为N的,由'('和')'组成的括号序列,你能找出这个序列中最长的合法括号子序列么?合法括号序列的 ...

随机推荐

  1. 用C++画光(二)——矩形

    在上篇文章的基础上,做了许多调整,修复了许多BUG.在解决bug的过程中,我逐渐领悟到一个要领:枯燥地一步步调试太痛苦了,找不到问题的根源!所以我选择将中间结果打到图片上.如: (注意,里面的点是我随 ...

  2. 用C++画光(一)——优化

    写在前面 在先前的画光系列中,实现实体几何.反射.折射等效果,但是最大的一个缺陷是复杂度太高.当采样是1024时,渲染时间直线上升(用4线程),以至好几个小时才能完成一副作品,实现太慢.然而,当我看到 ...

  3. 【NOI】9272 偶数个三

    题目 链接:bajdcc/ACM 描述 在所有的N位数中,有多少个数中有偶数个数字3?结果模12345.(1<=N<=10000) 样例输入 2 样例输出 73 方法一:穷举 评价:最简单 ...

  4. gulp的使用以及Gulp新手入门教程

    Gulp新手入门教程 原文  http://w3ctrain.com/2015/12/22/gulp-for-beginners/ Gulp 是一个自动化工具,前端开发者可以使用它来处理常见任务: 搭 ...

  5. 使用 esxtop 识别存储性能问题

    可以使用交互式 esxtop 实用程序提供连接到 VMware ESX 主机的各种设备的 I/O 衡量指标. 使用 esxtop 配置监控 要监控每个 HBA 的存储性能,请执行以下操作: 通过在命令 ...

  6. MySQL的使用笔记

    @Reference Manual (以下简称REF-M) 在官网,选择MySQL Server,选择Documentation,就可以下载了,建议下载PDF 注意版本要对应 很重要,需要的时候就go ...

  7. IE11不支持Selenium 2.0的解决方法

    题前话(Pre-words) 希望使用Selenium 2.0的人看到这篇文章能够收藏此文,以后遇到该问题,再也不用花费多余的时间进行research了!本文就是对网上所有千奇百怪各种各样的searc ...

  8. 屏幕相关操作(XE10.1+WIN8.164)

    相关资料: http://www.bianceng.cn/Programming/Delphi/201104/25455.htm http://blog.csdn.net/anbangs/articl ...

  9. 一款纯css3实现的响应式导航

    之前为大家介绍了好几款响应式导航.今天再给大家带来一款纯css3实现的响应式导航.这款导航还有个响应式的搜索框.废话少说,直接上图: 在线预览   源码下载 实现的代码. html代码: <di ...

  10. Intellij idea上传项目到github

    操作前提 1.安装了 git for windows客户端 2.配置了rsa公钥 3.设置了邮箱和用户名 详情请看上一篇博客http://www.cnblogs.com/520playboy/p/66 ...