您的位置:首页 > 其它

单调递增最长子序列-第一个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

下面贴代码

#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)

通过这些经典模型的研究,可以从多角度了解如何进行状态的划分,然后反复理解每一个转移方程的意义,在潜移默化之中,我们便可以达到动态规划的基本要求,做到以不变应万变。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  动态规划 递归 dp