动态规划(入门篇)
2018-02-19 19:07
148 查看
题目(poj1163):
73 8
8 1 0
2 7 4 4
4 5 2 6 5
(Figure 1)
Figure 1 shows a number triangle. Write a program that
calculates the highest sum of numbers passed on a route that starts at
the top and ends somewhere on the base. Each step can go either
diagonally down to the left or diagonally down to the right.
Input
Your program is to read from standard input. The first line contains
one integer N: the number of rows in the triangle. The following N
lines describe the data of the triangle. The number of rows in the
triangle is > 1 but <= 100. The numbers in the triangle, all integers,
are between 0 and 99.
Output
Your program is to write to standard output. The highest sum is
written as an integer.
Sample Input
5 7 3 8 8 1 0 2 7 4 4 4 5 2 6 5
Sample Output
30
题目要求: 找出从顶部到底部所经过数字之和最大的路径(不必给出具体路径)
题解:
直接递归方法
#include <stdio.h> int arr[101][101]; int n; int max(int x,int y) { return (x>y?x:y); } int maxSum(int i,int j) { if(i==n) return arr[i][j]; else { int x=maxSum(i+1,j); int y=maxSum(i+1,j+1); return max(x,y)+arr[i][j]; } } int main(void) { int i,j; scanf("%d",&n); for(i=1;i<=n;i++) { for(j=1;j<=i;j++) { scanf("%d",&arr[i][j]); } } printf("%d\n",maxSum(1,1)); return 0; }
缺点是中间的数字会被重复计算导致超时
第一种动态规划方法(用一个新数组来记录已经求出的值)
#include <stdio.h> int arr[101][101]; int temp[101][101]; int n; int max(int x,int y) { return (x>y?x:y); } int maxSum(int i,int j) { if(temp[i][j]!=-1) //这里判断该点的maxSum是否已经求出 return temp[i][j]; //若已求出直接返回 if(i==n) return arr[i][j]; else { int x=maxSum(i+1,j); int y=maxSum(i+1,j+1); temp[i][j]=max(x,y)+arr[i][j]; } return temp[i][j]; } int main(void) { int i,j; scanf("%d",&n); for(i=1;i<=n;i++) { for(j=1;j<=i;j++) { scanf("%d",&arr[i][j]); temp[i][j]=-1; } } printf("%d\n",maxSum(1,1)); return 0; }
缺点:得定义一个新数组,浪费空间
递推型动态规划
分析:先写出最后一行,4 5 2 6 5
然后分析倒数第二行,2 7 4 4,其中第一个数可以跟4或5相加,显然加5的和7更大,所以将7保存在原本2的位置上。
同样道理分析接下来的几个数,得到新的倒数第二行7 12 10 10,即代表倒数第二行对应的值最大的路径的值。
同样的道理递推到倒数第三,倒数第四…直到第一行,即求出第一行的值最大的路径的值
#include <stdio.h> int arr[101][101]; int n; int *maxSum; int max(int x,int y) { return (x>y?x:y); } int main(void) { int i,j; scanf("%d",&n); for(i=1;i<=n;i++) { for(j=1;j<=i;j++) { scanf("%d",&arr[i][j]); } } maxSum=arr ; for(i=n-1;i>0;i--) { for(j=1;j<=i;j++) { maxSum[j]=max(maxSum[j],maxSum[j+1])+arr[i][j]; } } printf("%d\n",maxSum[1]); return 0; }
参考博客:http://blog.csdn.net/baidu_28312631/article/details/47418773
相关文章推荐
- 动态规划[入门]2-循环数组最大子段和
- 算法导论 动态规划入门之装配线调度问题
- 动态规划入门一
- 动态规划入门 数字三角形(POJ1163)
- 动态规划入门-矩阵取数
- 【动态规划32讲】第三节 动态规划入门
- 【算法竞赛入门经典】动态规划初步 例题9-7 UVa11584
- 算法艺术与信息学竞赛 之 动态规划入门
- 动态规划(一)入门例子
- poj 3176 1163【动态规划】【入门】
- 【算法设计与数据结构】动态规划入门——URAL 1119 Metro
- HDU动态规划入门练习题
- UVA 10285 Longest Run on a Snowboard(记忆化搜索|动态规划入门)
- 简单动态规划(4)——从入门到放弃
- 通过金矿模型介绍动态规划 (很好的动态规划入门介绍)
- 动态规划之插头DP入门
- VF 动态规划系列dp入门
- 动态规划入门级教学(leetcode)121.Best Time to Buy and Sell Stock
- 动态规划(DP)之入门学习-数字三角形
- 动态规划 入门篇(一)