DP的学习和使用
2011-03-24 22:57
127 查看
1. 如果自顶向下的程序不好设计的话,就变成自底向上的好了
2. 如果大量的递归导致程序时间的拖延,那么就以空间换时间,记录递归的中间结果
3. Max sum 问题
一般人的想法是:从a[i] 的每一个i开始遍历一次数组,分别计算出每一次遍历的最大值,最后将所有的最大值对比。
程序时间复杂度为o(n*n)
使用DP,只需要 o(n) 即可
关于代码,我大概看懂了,但是没明白为什么这样就算是动态规划。。。
进阶的情况:线性变二维
想法降回线性
求序列的最大上升序列(可以不连续)
/* goso : Dynamic Programming :: 数塔的问题 思想就是不断的上溯,自底向上求解 如果自顶向下求解的话非常麻烦 */ #include <stdio.h> #define MAX_ARRAY 0xff main() { int i=0,j=0,t=0; int a[MAX_ARRAY][MAX_ARRAY] = {0}; while (scanf("%d",&t) != EOF) // 又学到了一种用法 { for (i=0 ; i<t ; ++i) { for (j=0 ; j<=i; ++j) { scanf("%d",&a[i][j]); } } // 接收完成 for (i=t-2; i>=0 ; --i) { for (j=0; j<=i ; ++j) { a[i][j] += a[i+1][j] > a[i+1][j+1] ? a[i+1][j] : a[i+1][j+1]; } } } printf("%d",a[0][0]); }
2. 如果大量的递归导致程序时间的拖延,那么就以空间换时间,记录递归的中间结果
/* 记录递归的中间结果,降低递归程序进入的次数,减少程序的时间消耗 */ #include <stdio.h> static int e[21][21][21]; int w(int a,int b,int c) { if (a <= 0 || b <= 0 || c <= 0) return 1; else if(a > 20 || b > 20 || c > 20) return w(20,20,20); else if(a < b && b < c) { if (e[a][b][c]) return e[a][b][c]; else { e[a][b][c] = w(a,b,c-1) + w(a,b-1,c-1) - w(a,b-1,c); return e[a][b][c]; } } else { if (e[a][b][c]) return e[a][b][c]; else { e[a][b][c] = w(a-1,b,c) + w(a-1,b-1,c) + w(a-1,b,c-1) - w(a-1,b-1,c-1); return e[a][b][c]; } } } main() { int a=0,b=0,c=0,res=0; scanf("%a %b %c",&a,&b,&c); res = w(a,b,c); printf("%d",res); }
3. Max sum 问题
一般人的想法是:从a[i] 的每一个i开始遍历一次数组,分别计算出每一次遍历的最大值,最后将所有的最大值对比。
程序时间复杂度为o(n*n)
使用DP,只需要 o(n) 即可
关于代码,我大概看懂了,但是没明白为什么这样就算是动态规划。。。
/* Max sum sequence */ #include <stdio.h> #define MAX_ARRAY 0xff main() { int a[MAX_ARRAY] = {0}; int n=0,i=0; int sum=0,maxsum=-9999; // C语言中最小值那个宏叫什么来? int start=0,end=0,tmp=0; scanf("%d",&n); for (;i<n;++i) { scanf("%d",&a[i]); // store in array } for (i=0; i<n; ++i) { sum += a[i]; if (sum > maxsum) { maxsum = sum; start = tmp; end = i; } if (sum < 0) { tmp = i+1; sum = 0; } } printf("%d/t%d/t%d/n",maxsum,start,end); }
进阶的情况:线性变二维
想法降回线性
/* Max sum matrix */ /* 寻找一个方法把二维变成一维 */ #include <stdio.h> #define MAX_ARRAY 0xff main() { int m=0,n=0; int i=0,j=0,k=0,l=0; int a[MAX_ARRAY][MAX_ARRAY] = {0}; int seed[MAX_ARRAY] = {0}; scanf("%d %d",&m,&n); for (i=0; i<m; ++i) { for (j=0; j<m; ++j) { scanf("%d",&a[i][j]); } } for (i=0; i<m; ++i) { for (j=i; j<m; ++j) /// 这里的i,j都是对行进行遍历,跟平时的不同 { for (k=0; k<n; ++k) { seed[k]=0; for (l=i; l<=j; ++l) { seed[k] += a[l][k]; } } // call a procedure of 1 //save the biggest integer } } }
求序列的最大上升序列(可以不连续)
/* Super Jump! Jump! Jump! */ #include <stdio.h> #define MAX_ARRAY 0xff main() { int a[MAX_ARRAY] = {1,4,7,3,5,6}; int b[MAX_ARRAY] = {1}; int i=0,j=0,maxb=0,maxnum=0; for (i=0 ; i<6 ; ++i) { // 找比自己小的数字中的和的最大值 maxb = 0; for (j=0; j<i; ++j) { if (a[j] < a[i] && b[j] > maxb) { maxb = b[j]; } } b[i] = maxb+a[j]; if (b[i] > maxnum) { maxnum = b[i]; } } printf("%d",maxnum); }
相关文章推荐
- 想学习Nunit的使用
- Maven学习一:使用Myeclipse创建Maven项目
- AngularJS学习笔记--使用angular.extend()实现工厂模式
- 手把手教你使用eclipse+qemu+gdb来单步调试ARM内核【学习笔记】
- IOS开发---菜鸟学习之路--(六)-UITableView几个方法的使用说明
- springMVC学习指南<附录>tomcat的使用
- JavaWeb学习总结(二)——Tomcat服务器学习和使用(一)
- MVC使用T4模板生成其他类的具体实现学习笔记2
- 关于struts2.5.2 初步学习 遇到的几点改变以及使用通配符调用无效的问题
- 学习和使用web标准的十大理由
- 使用pytorch进行迁移学习
- 安卓学习记录,BaseAdapter的使用
- hadoop生态系统学习之路(十二)cloudera manager的简单使用
- 学习笔记之——简单使用facebook/fresco库加载res本地静态图片
- Mysql学习总结(31)——MySql使用建议,尽量避免这些问题
- 通过代码学习C#&.NET——委托使用(线程、任务)
- C++11学习笔记-----互斥量以及条件变量的使用
- stenciljs 学习九 使用jsx
- 【Cocos2d-X开发学习笔记】第14期:动作类之基本动作的使用(下)
- Json学习总结(1)——Java和JavaScript中使用Json方法大全