单调递增最长子序列-第一个dp(动态规划)
2016-06-21 11:37
204 查看
也许你和我一样,刚接触动态规划,一头雾水,看也看不懂,但作为过来人,写下一点东西,一方面,增加自己的记忆,另一方面,给你们点干货。dp(dynamic programming);
1.动态规划,就是把计算过程中产生的中间结果静态地保存起来,后面再用到这些中间结果的时候就不用再算一遍,而是直接读取。
2.动态规划是递归,是缓存,是用空间来换取时间。
3.原问题的解如何由子问题的解组合而成。
**一个正常的思维过程应该是:
1.OK 这个问题需要用到递归的思想….
2.开始写递归…
3.哇 算对了..
4. 诶?怎么感觉有很多sub problem被重复计算了 干 复杂度到了 2^N
5. 好吧 dp一下 弄个table或者是tree来memoization一下…
6. 优化成功
(当然如果你搞竞赛以上过程不适合你 如果你只是纯粹觉得理解dp是一件有趣的事情或者对算法抱有纯粹的兴趣 那么我觉得以上的过程很适合你)
作者:Pusheen Cherish
链接:http://www.zhihu.com/question/23995189/answer/36008790
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。**
如果你们先详细了解,入门动态规划,那就看看知乎这个页面
http://www.zhihu.com/question/23995189
下面贴代码
很多东西,都是接力下去的,写博客,就是一种接力,dp也是一种接力,后辈,好好加油,我也加油
重点研究几类经典问题
在理解了动态规划的一些概念之后,要能做到用动态规划解题,其中重点研究几类经典问题是很有必要的。就近几年的比赛题目而言,往往都可以转化为我们已知的经典模型。下面介绍几个经典模型:
1、按状态类型分
编号(长度)动态规划类,题库:最长不下降子序列;拦截导弹(noip99);花店橱窗布置(ioi99)。
区间动态规划类,题库:石子合并;邮局(ioi2000)。
坐标动态规划类,题库:棋盘分割(noi99)。
数轴动态规划类,题库:01背包;装箱问题(noip01)。
树型动态规划类,题库:选课(ctsc97),贪食的九头龙(noi02)。
集合动态规划(状态压缩)类,题库:购物(ioi95)。
2、按转移方式分
存在性:01统计(ctsc99);Catalan数
划分问题:分割点有序类,题库:成绩最大(noip00)
分割点无序类,题库:石子合并(noi95);加分二叉树(noip03);括号序列
3、路径问题:方格取数(noip00);花店橱窗布置(ioi99)
通过这些经典模型的研究,可以从多角度了解如何进行状态的划分,然后反复理解每一个转移方程的意义,在潜移默化之中,我们便可以达到动态规划的基本要求,做到以不变应万变。
1.动态规划,就是把计算过程中产生的中间结果静态地保存起来,后面再用到这些中间结果的时候就不用再算一遍,而是直接读取。
2.动态规划是递归,是缓存,是用空间来换取时间。
3.原问题的解如何由子问题的解组合而成。
**一个正常的思维过程应该是:
1.OK 这个问题需要用到递归的思想….
2.开始写递归…
3.哇 算对了..
4. 诶?怎么感觉有很多sub problem被重复计算了 干 复杂度到了 2^N
5. 好吧 dp一下 弄个table或者是tree来memoization一下…
6. 优化成功
(当然如果你搞竞赛以上过程不适合你 如果你只是纯粹觉得理解dp是一件有趣的事情或者对算法抱有纯粹的兴趣 那么我觉得以上的过程很适合你)
作者:Pusheen Cherish
链接:http://www.zhihu.com/question/23995189/answer/36008790
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。**
如果你们先详细了解,入门动态规划,那就看看知乎这个页面
http://www.zhihu.com/question/23995189
下面贴代码
#include <stdio.h> #include <string.h> char a[10001]; int dp[10000]; int f(int len) { int i,j,ans,m;//ans是这个字符串中最长子序列的值 dp[0]=1,ans=1;//如果这个字符串存在,那就存在dp[0],ans[1]; for(i=1;i<len;i++)//遍历数组 { m=0;//如果a[i]比前面的所有都小,dp[i]=1; for(j=0;j<i;j++)//获得从i=0,到i=i之间a[i]可以连续递增的值 { if(dp[j]>m&&a[j]<a[i]) m=dp[j]; } dp[i]=m+1;//找到那个i之前的最大值,并加1 if(dp[i]>ans)//不断获得最大值 ans=dp[i]; } return ans; } int main() { int n,len; scanf("%d",&n); while(n--) { scanf("%s",&a); len=strlen(a); printf("%d\n",f(len)); } return 0; }
很多东西,都是接力下去的,写博客,就是一种接力,dp也是一种接力,后辈,好好加油,我也加油
重点研究几类经典问题
在理解了动态规划的一些概念之后,要能做到用动态规划解题,其中重点研究几类经典问题是很有必要的。就近几年的比赛题目而言,往往都可以转化为我们已知的经典模型。下面介绍几个经典模型:
1、按状态类型分
编号(长度)动态规划类,题库:最长不下降子序列;拦截导弹(noip99);花店橱窗布置(ioi99)。
区间动态规划类,题库:石子合并;邮局(ioi2000)。
坐标动态规划类,题库:棋盘分割(noi99)。
数轴动态规划类,题库:01背包;装箱问题(noip01)。
树型动态规划类,题库:选课(ctsc97),贪食的九头龙(noi02)。
集合动态规划(状态压缩)类,题库:购物(ioi95)。
2、按转移方式分
存在性:01统计(ctsc99);Catalan数
划分问题:分割点有序类,题库:成绩最大(noip00)
分割点无序类,题库:石子合并(noi95);加分二叉树(noip03);括号序列
3、路径问题:方格取数(noip00);花店橱窗布置(ioi99)
通过这些经典模型的研究,可以从多角度了解如何进行状态的划分,然后反复理解每一个转移方程的意义,在潜移默化之中,我们便可以达到动态规划的基本要求,做到以不变应万变。
相关文章推荐
- C#递归算法之分而治之策略
- 有关数据库SQL递归查询在不同数据库中的实现方法
- C#中的递归APS和CPS模式详解
- WinForm实现按名称递归查找控件的方法
- C#递归方法实现无限级分类显示效果实例
- 使用SqlServer CTE递归查询处理树、图和层次结构
- C#递归算法之打靶算法分析
- C#中的尾递归与Continuation详解
- C++动态规划之最长公子序列实例
- C++动态规划之背包问题解决方法
- C#递归实现显示文件夹及所有文件并计算其大小的方法
- php递归创建目录的方法
- PHP递归创建多级目录
- Javascript递归打印Document层次关系实例分析
- C#递归算法寻找数组中第K大的数
- C++使用递归方法求n阶勒让德多项式完整实例
- C#用递归算法解决经典背包问题
- oracle 使用递归的性能提示测试对比
- 使用curl递归下载软件脚本分享
- Perl脚本实现递归遍历目录下的文件