动态规划算法——C++实现经典案例——中级

从简到繁,从易到难,按部就班。切近亲力亲为,动手写代码。ios


动态规划的详细知识点请参考:http://blog.csdn.net/misayaaaaa/article/details/71794620算法


动态规划算法的难点在于 从实际问题中抽象出动态规划表dp,dp通常是一个数组,多是一维的也多是二维的,也多是其余的数据结构整个求解过程就能够用一个最优决策表来描述,最优决策表能够是一个二维表,其中行表示决策的阶段,列表示问题状态,表格须要填写的数据通常对应此问题的在某个阶段某个状态下的最优值(如最短路径,最长公共子序列,最大价值等),填表的过程就是根据递推关系,从1行1列开始,以行或者列优先的顺序,依次填写表格,最后根据整个表格的数据经过简单的取舍或者运算求得问题的最优解:数组

f(n,m)=max{f(n-1,m), f(n-1,m-w[n])+P(n,m)}数据结构


最长递增子序列问题:给定数组arr,返回arr的最长递增子序列的长度,好比arr=[2,1,5,3,6,4,8,9,7],最长递增子序列为[1,3,4,8,9]返回其长度为5.
spa

C++实现:.net


/***************************************************************************  
 *  @file       main.cpp  
 *  @author     MISAYAONE  
 *  @date       15  May 2017  
 *  @remark     15  May 2017   
 *  @theme      Find the longest sequence in an array   
 ***************************************************************************/

#include <iostream>

#define N 10     //数组长度
using namespace std;

int main(int argc,char** argv)
{
	int dp[N];   //存放决策表
	dp[0] = 1;
	int a[N] = {1,2,3,4,5,6,9,7,8,10};
	
	for (int i = 1;i < N;++i)
	{
		int temp = 0;
		for (int j = 0;j < i;++j)
		{
			if (dp[j]+1>dp[i] && a[i]>a[j])
			{
				dp[i] = dp[j]+1;			
			}
		}
		if (temp < dp[i])
		{
			temp = dp[i];
		}
	}

	for (int i = 0;i<10;++i)
	{
		cout<<dp[i];
	}
	system("pause");
	return 0;
}

最长公共子序列问题
:给定两个字符串str1和str2,返回两个字符串的最长公共子序列

例如:str1="1A2C3D4B56",str2="B1D23CA45B6A","123456"和"12C4B6"都是最长公共子序列,返回哪个都行。
分析:本题是很是经典的动态规划问题,假设str1的长度为M,str2的长度为N,则生成M*N的二维数组dp,dp[i][j]的含义是str1[0..i]与str2[0..j]的最长公共子序列的长度。
dp值的求法以下:dp[i][j]的值必然和dp[i-1][j],dp[i][j-1],dp[i-1][j-1]相关,结合下面的代码来看,咱们其实是从第1行和第1列开始计算的,而把第0行和第0列都初始化为0,这是为了后面的取最大值在代码实现上的方便,dp[i][j]取三者之间的最大值。
code

C++实现:blog

/***************************************************************************  
 *  @file       main.cpp  
 *  @author     MISAYAONE  
 *  @date       15  May 2017  
 *  @remark     15  May 2017   
 *  @theme      Find the longest same sequence in two array   
 ***************************************************************************/

#include <iostream>
#include <algorithm>
using namespace std;

int main(int argc,char** argv)
{
	string A = "123ABChuj";
	string B = "123ABCabc";
	int dp[20][20] = {};
	for (int i=0;i<A.size();++i)
	{
		for (int j=0;j<B.size();++j)
		{
			if (A[i] == B[j])
			{
				dp[i+1][j+1] = dp[i][j] +1;	
			}
			else
			{
				dp[i+1][j+1] = max(dp[i+1][j],dp[i][j+1]);
			}
		}
	}
	cout<<dp[A.size()][B.size()];
	system("pause");
	return 0;
}