最近在做搜狗编程的时候,遇到了动态规划一类的问题,感觉很有意思。写此博文总结之。
首先先简单叙述下什么是动态规划。
(下面部分概念参考自:百度百科)
把多阶段过程转化为一系列单阶段问题,利用各阶段之间的关系,逐个求解,创立了解决这类过程优化问题的新方法。
对于动态规划问题的一些理解(个人看法,可能有误):
大多数动态规划问题都可以用蛮力法或者递归(深度搜索)的思路来解决,但是用动态规划就好了很多;一个很著名的例子,斐波那契数列的求解,用递归当然OK,但是计算下一个数的时候,用到前一个的数的结果,会好很多,我个人认为从概念角度来看,这种计算斐波那契数列的算法(保留上一步的值)也属于动态规划。
下面来介绍2个动态规划的问题。
问题描述:在一个无序的序列 a1 , a2 ,…, am 里,找到一个最长的序列,满足 ai≤aj…≤ak ;且 i<j<k ;
动态规划解题思路:
引入一个状态opt[i]数组,该状态记录的信息是,到该位置,它的最长非将子序列的长度。
下面是我写的C++实现。
#include<iostream>
using namespace std;
int main()
{
int a[10]={22,12,1,23,1000,-1,98,99,0,4};
int opt[10]={0};
opt[1]=1;
for(int i=1;i<10;i++)
{
for(int j=0;j<i;j++)
{
if(a[i]>=a[j]&&opt[j]+1>opt[i])
{
opt[i]=opt[j]+1;
}
}
}
int max=0;
for(int i=0;i<10;i++)
{
if(max<opt[i])
max=opt[i];
}
cout<<max<<endl;
return 0;
}
当然,该问题可以用递归算法求解,用到深度优先搜索算法。有兴趣可实现下,但是明显不如动态规划的办法。
问题描述:对于序列S和T,求它们的最长公共子序列。例如X={A,B,C,B,D,A,B},Y={B,D,C,A,B,A}则它们的lcs是{B,C,B,A}和{B,D,A,B}。
《算法导论》上给出了该问题的求解算法伪代码描述。
用C++实现如下。
#include<iostream>
#include<string>
using namespace std;
string a,b;
int num[501][501]={0}; ///记录中间结果的数组
int flag[501][501]={0}; ///标记数组,用于标识下标的走向,构造出公共子序列
void LCS(); ///动态规划求解
void getLCS(); ///采用倒推方式求最长公共子序列
int main()
{
a="ABCBDAB";
b="BDCABA";
LCS();
cout<<"fuck:"<<num[(int)a.size()][(int)b.size()]<<endl;
getLCS();
return 0;
}
void LCS()
{
int i,j;
for(i=1;i<=(int)a.size();i++)
{
for(j=1;j<=(int)b.size();j++)
{
if(a[i-1]==b[j-1]) ///注意这里的下标是i-1与j-1
{
num[i][j]=num[i-1][j-1]+1;
flag[i][j]=1; ///斜向上标记
}
else if(num[i-1][j]>=num[i][j-1])
{
num[i][j]=num[i-1][j];
flag[i][j]=2; ///向上标记
}
else
{
num[i][j]=num[i][j-1];
flag[i][j]=3; ///向左标记
}
}
}
cout<<num[(int)a.size()][(int)b.size()]<<endl;
}
void getLCS()
{
char res[500];
int i=(int)a.size();
int j=(int)b.size();
int k=0; ///用于保存结果的数组标志位
while(i>0 && j>0)
{
if(flag[i][j]==1) ///如果是斜向上标记
{
res[k]=a[i-1];
k++;
i--;
j--;
}
else if(flag[i][j]==2) ///如果是向右标记
j--;
else if(flag[i][j]==3) ///如果是向下标记
i--;
}
for(i=k-1;i>=0;i--)
cout<<res[i];
cout<<endl;
}
《算法导论》
博文1:http://www.cnblogs.com/wuyuegb2312/p/3281264.html#q3
博文2:http://www.cnblogs.com/xudong-bupt/archive/2013/03/15/2959039.html
博文3:http://www.cnblogs.com/dartagnan/archive/2011/08/29/2158230.html