DP
2016-04-15 00:00
155 查看
第一次学习动态规划算法,借这篇文章总结一下
矩阵取数问题
一个N*N矩阵中有不同的正整数,经过这个格子,就能获得相应价值的奖励,从左上走到右下,只能向下向右走,求能够获得的最大价值。
例如:3X3的方格。
1 3 3
2 1 3
2 2 1
能够获得的最大价值为:11。
输入
第1行:N,N为矩阵的大小。(2 <= N <= 500)
第2 - N + 1行:每行N个数,中间用空格隔开,对应格子中奖励的价值。(1 <= N[i] <= 10000)
输出
输出能够获得的最大价值。
假设经过某一点N1的路径为最大值的路径,可以得到:到达N1点的最大值的路径是N1点的左侧的点N2或N1上面的点N3中值较大的点加上N1点的值
即f(N1) = max(f(N2), f(N3)) + N1。
如果要到一条最大值的路径,我们可以从左上角第一个格子开始把到达每一点最大值给求出来,这样我们可以得到到达矩阵上每一点的最大值,右下角的最大值也就是它上方或左方的较大的点加上当前点的值。
可以得到代码
从这道题目中可以得到DP中两个概念:状态、状态转移方程。在上面这道题目中的状态就是到达某点的最大值,而状态转移方程也就是f(N1) = max(f(N2), f(N3)) + N1。
最大字段和
给出一个整数数组a(正负数都有),如何找出一个连续子数组(可以一个都不取,那么结果为0),使得其中的和最大?当所给的整数均为负数时和为0。
例如:-2,11,-4,13,-5,-2,和最大的子段为:11,-4,13。和为20。
解决这个问题可以用多种方法:枚举、分治、动态规划。下面用动态规划解决这道题
对于数组中的a[i],我们要求出子段和,要么加上a[i],要么不加。如果不加a[i]的值的话,也就相当于从i开始。什么时候不加a[i]?当i-1的字段和为负数的时候,也就没有必要去加了。可以得到状态转移方程 f(i) = max(f(i-1)+a[i], a[i]) 把a[i]提出来,得:f(i) = max(f(i-1), 0)+ a[i]
可以得到问题的解
via:http://www.hawstein.com/posts/dp-novice-to-advanced.html
via:https://www.51nod.com/tutorial/index.html#!tutorialId=1
矩阵取数问题
一个N*N矩阵中有不同的正整数,经过这个格子,就能获得相应价值的奖励,从左上走到右下,只能向下向右走,求能够获得的最大价值。
例如:3X3的方格。
1 3 3
2 1 3
2 2 1
能够获得的最大价值为:11。
输入
第1行:N,N为矩阵的大小。(2 <= N <= 500)
第2 - N + 1行:每行N个数,中间用空格隔开,对应格子中奖励的价值。(1 <= N[i] <= 10000)
输出
输出能够获得的最大价值。
假设经过某一点N1的路径为最大值的路径,可以得到:到达N1点的最大值的路径是N1点的左侧的点N2或N1上面的点N3中值较大的点加上N1点的值
即f(N1) = max(f(N2), f(N3)) + N1。
如果要到一条最大值的路径,我们可以从左上角第一个格子开始把到达每一点最大值给求出来,这样我们可以得到到达矩阵上每一点的最大值,右下角的最大值也就是它上方或左方的较大的点加上当前点的值。
可以得到代码
#include <stdio.h> #include <stdlib.h> int max(int x, int y) { return x > y ? x : y; } int main() { int N; scanf("%d", &N); int **arr; int **res; arr = (int **)malloc(N* sizeof(int *)); for (int i = 0; i < N; i++) { arr[i] = (int*)malloc(N* sizeof(int)); } res = (int **)malloc((N+1)* sizeof(int *)); for (int i = 0; i < N+1; i++) { res[i] = (int*)malloc((N+1)* sizeof(int)); } for (int i = 0; i < N; i++) { for (int j = 0; j < N; j++) { scanf("%d", &arr[i][j]); } } for (int i = 0; i < N + 1; i++) { res[0][i] = 0; res[i][0] = 0; } for (int i = 1; i < N + 1; i++) { for (int j = 1; j < N + 1; j++) { res[i][j] = max(res[i - 1][j], res[i][j - 1]) + arr[i-1][j-1]; } } printf("%d",res ); return 0; }
从这道题目中可以得到DP中两个概念:状态、状态转移方程。在上面这道题目中的状态就是到达某点的最大值,而状态转移方程也就是f(N1) = max(f(N2), f(N3)) + N1。
最大字段和
给出一个整数数组a(正负数都有),如何找出一个连续子数组(可以一个都不取,那么结果为0),使得其中的和最大?当所给的整数均为负数时和为0。
例如:-2,11,-4,13,-5,-2,和最大的子段为:11,-4,13。和为20。
解决这个问题可以用多种方法:枚举、分治、动态规划。下面用动态规划解决这道题
对于数组中的a[i],我们要求出子段和,要么加上a[i],要么不加。如果不加a[i]的值的话,也就相当于从i开始。什么时候不加a[i]?当i-1的字段和为负数的时候,也就没有必要去加了。可以得到状态转移方程 f(i) = max(f(i-1)+a[i], a[i]) 把a[i]提出来,得:f(i) = max(f(i-1), 0)+ a[i]
可以得到问题的解
#c过不了oj 改为python -、- def MaxSubSeq(arr, N): sum = temp = 0 for i in arr: if temp > 0: temp += i else : temp = i if temp > sum : sum = temp if sum < 0: sum = 0 return sum N = int(input()) arr = [] for i in range(N): arr.append( int( input())) print(MaxSubSeq(arr, N))
via:http://www.hawstein.com/posts/dp-novice-to-advanced.html
via:https://www.51nod.com/tutorial/index.html#!tutorialId=1
相关文章推荐
- struts2部分总结
- Ajax简单总结
- Spring3 整合MyBatis3 配置多数据源 动态选择SqlSessionFactory
- SpringMVC+Mybatis声明式事务分析
- 去除UITableViewCell左侧分割线15px空白
- ELK 索引抽取模板(中文索引配置not_analyzed,才能在kibana中使用terms)
- 听说微信红包有7种玩法,你知道的有几种?
- 删除对象的list出现的问题解决
- listview setEmpty
- 简单的线程池管理多线程
- Log4j配置详解
- sleep和wait区别
- 线程池-newFixedThreadPool、newCachedThreadPool、
- 修改Tomcat Connector运行模式,优化Tomcat运行性能
- SpringMVC注解
- Spring MVC控制流程与简易配置方案
- mysql安装到win10系统最后一步出错未响应
- 修改Jenkins的JENKINS_HOME路径
- js读取解析JSON类型数据
- 使用jQuery解析JSON数据