`
- 浏览:
244484 次
- 性别:
- 来自:
北京
-
动态规划算法两要素
•递归方程式(状态转移方程式)
•保存子问题的解
无穷数列1,1,2,3,5,8,13,21,34,55,…,称为Fibonacci数列。它可以递归地定义为
1 n = 0
F(n) = 1 n = 1
F(n – 2) + F(n – 1) n > 1
保存子问题的解
#define MAX 1000
__int64 temp[MAX] = {0};
__int64 fibonacci(int n)
{
int i = 0;
temp[0] = 1;
temp[1] = 1;
for(i=2; i<= n; i++)
{
temp[i] = temp[i-1] + temp[i-2];
}
return temp[n];
}
基本思想:将待求解的问题分解成若干个相互联系的子问题,先求解子问题,然后从这些子问题的解得到原问题的解(多阶段决策);
对于重复出现的子问题,只在第一次遇到的时候对它进行求解,并把答案保存起来,让以后再次遇到时直接引用答案,不必重新求解 (填表)。
动态规划算法步骤
(1)找出最优解的性质,并刻画其结构特征。
(2)递归地定义最优值
(3)以自底向上的方式计算出最优值
(4)根据计算最优值时得到的信息,构造一个最优解
例子1:最大子段和
最大字段和问题,即给定n个整数(可能有0和负数)组成的序列a1 a2 a3.......an, 求其最大连续子段和。如有(-2, 11, -4, 13, -5, -2),则最大子段和 11-4+13=20。
#include <stdlib.h>
#include <stdio.h>
#include <limits.h>
#define N 14
int MaxSumDP(int *a, int n); //动态规划法
int a[N] = {9, -7, 3,-1, 4, 5, -10, -2, 9, 1, -3, -4, 6, 2};
int b[N];//b[i]表示以a[i]为最后一个元素的最大子段和
int main()
{
printf("The MaxSubSum using DP: %d\n", MaxSumDP(a, N));
getchar();
return 0;
}
int MaxSumDP(int *a, int n) //动态规划法
{
int i, maxSum = 0;
if(a[0] > 0)
maxSum=b[0]=a[0];
for(i=1; i<n; ++i)
{
b[i] = (b[i-1]+a[i] > 0) ? (b[i-1]+a[i]) : 0;//记录每个子结构的和,如果前面的i-1
if(maxSum < b[i]) //已经是小于0,后面的直接赋值就a[i]
maxSum = b[i];
}
return maxSum;
}
可以看出动态规划法的复杂度只有O(n),但需要O(n)的空间,而分治法的复杂度是O(nlogn),可见动态规划法更优秀。在动态规划法中,b[n]数组的元素b[i]代表的意思是:
如果a[0]=0,则b[0]=a[0],否则b[0]=0,然后对于b[i]
b[i] = MAX( b[i -1] + a[i], 0 );
即b[i]等于b[i-1]+a[i] 和 0 中的较大者
分享到:
Global site tag (gtag.js) - Google Analytics
相关推荐
动态规划最大子序列和 Gabe 动态规划是解决复杂问题的一种方法,它将问题分解成小的子问题,然后通过解决这些子问题来解决原始问题。最大子序列和问题是一种经典的动态规划问题,它可以通过使用动态规划算法来解决...
- 在计算过程中记录下 `d[]` 数组中的最大值,这个值即为所求的最长单调递增子序列的长度。 #### 代码实现 下面是一段 C++ 代码示例,展示了如何使用动态规划解决上述问题: ```cpp #include #include using ...
以下是动态规划解决最长递增子序列的步骤: 1. 初始化:创建一个长度为n(数组长度)的dp数组,所有元素都初始化为1。因为每个元素本身至少可以构成一个长度为1的递增子序列。 2. 遍历数组:对于数组中的每个元素...
求解最大子序列、最长递增子序列、最长公共子串、最长公共子序列. http://blog.csdn.net/ssuchange/article/details/17341693
根据给定的文件信息,我们将深入探讨两个关键的IT领域知识点:动态规划在寻找最长单调递增子序列中的应用以及动态规划在图像压缩算法中的作用。 ### 一、动态规划与最长单调递增子序列 #### 知识点概述: **最长...
总结,求出最长上升子序列并打印其元素是一个典型的动态规划问题,它可以通过建立状态转移方程并回溯找到具体序列。了解和掌握这种问题的解决方法对于提升编程能力,特别是在算法设计和复杂问题求解方面,都有着重要...
最长公共子序列(Longest Common Subsequence,LCS)是计算机科学中一种经典的字符串问题,主要涉及算法设计与分析,特别是在动态规划领域的应用。在这个问题中,我们需要找到两个或多个字符串之间的最长子序列,这...
计算机算法分析与设计最大连续子序列 计算机算法分析与设计最大连续子序列是计算机...解决该问题需要使用动态规划法,读取输入数据,记录最大和和历史最大的和,并输出最大和、最大连续子序列的第一个和最后一个元素。
动态规划是一种强大的算法工具,常用于解决复杂的问题,如寻找序列中的最大子序列和。在“2.1动态规划最大子段和”这个主题中,我们主要关注如何使用动态规划来找出一个数组或序列中连续子序列的最大和,即使这个...
最长公共子序列(Longest Common Subsequence,LCS)问题是一个经典的计算机科学问题,主要涉及字符串处理和动态规划算法。在本场景中,我们使用C#编程语言来解决这个问题。C#是一种多范式编程语言,广泛应用于开发...
“动态规划法求解最长公共子序列问题&0-1背包问题” 动态规划是一种非常重要的算法设计方法,应用于解决很多复杂的问题。动态规划法可以将问题分解成若干个小问题,然后通过解决每个小问题来解决整个问题。在实验2...
在动态规划中,我们可以定义一个二维数组 `dp[i][j]`,其中 `dp[i][j]` 表示序列X的前i个字符和序列Y的前j个字符的最长公共子序列的长度。 3. **状态转移方程**: - 如果 `X[i] == Y[j]`,那么 `dp[i][j] = dp[i-...
实验5.4的主题是求解最大子序列和以及最大子矩阵的问题,这涉及到经典的动态规划算法。最大子序列和问题是一维数组中最长的连续子序列,使得子序列的和最大。最大子矩阵和问题是在二维矩阵中找到一个矩形区域,其...
在LCS问题中,动态规划的核心思想是构建一个二维数组C,其中C[i][j]表示X的前i个字符与Y的前j个字符的最长公共子序列的长度。通过逐步填充这个数组,我们可以找到整个序列的LCS长度。 #### 分析给定代码 下面是对...
在本例中,提供的文件是使用C++语言实现的动态规划解法,名为“最长公共子序列问题 动态规划法.cpp”。 动态规划是一种解决问题的有效方法,它通过将复杂问题分解为一系列更小的子问题来求解。在解决LCS问题时,...
- 如果不相等,则当前的最长公共子序列长度取相邻位置的最大值。 ```c for (i = 1; i ; i++) for (j = 1; j ; j++) if (x[i-1] == y[j-1]) L[i][j] = L[i-1][j-1] + 1; else if (L[i-1][j] > L[i][j-1]) L[i...
在这个问题中,我们要在一系列整数中找到连续子序列(子数组),使得这个子序列的和最大。 动态规划的核心思想是自底向上地解决问题,通过建立状态转移方程来逐步求解。对于最大子段和问题,我们可以定义一个二维...
动态规划——最大连续子序列和一维最大连续子序列和[x] LeetCode 53 Maximum Subarray设$d[i]$表示以序列中$s[i]$结尾的最大
在本主题“动态规划算法中对子序列的一些模板”中,我们将深入探讨几种与子序列相关的经典问题及其解决方案。 1. **最长公共子序列(Longest Common Subsequence, LCS)** - LCS问题是寻找两个或多个序列中的最...
在编程领域,动态规划是一种强大的算法,常用于解决复杂的问题,比如找到数组中的最大子序列和。本篇文章将深入探讨如何使用C++语言来实现这一算法。 动态规划(Dynamic Programming,简称DP)是一种通过将复杂问题...