动态规划算法的细想是:
将待求解问题分解成若干子问题,这些子问题的解题过程都是相对独立的,既是每一个决策之间都是互不影响的,但是各步决策之间有着某种递推关系。然后由子问题解得原问题的解。在动态规划算法里,我们记录每一个子问题的解,当解下一个问题时,先在记录中寻找该问题是否被解决,若不被解决,则继续计算。这样就降低了时间复杂度。
他与分治算法不同的是:分治算法也会将原问题分解成若干的子问题,而这些子问题的性质是与原问题相同的,就是说可以用同一种方法解各子问题,只是问题规模小了而已。相对于贪心算法,他们都具有最优子结构的性质。但是贪心算法能解的问题就是局部最优能导致全局最优的问题。只有一部分问题具有该性质。贪心算法能解一部分动态规划所能解的问题,解题效率比动态规划的高。
以下是我参照王晓东编写的《计算机算法设计与分析》写关于结决最大字段和问题:
该算法是求某子段段的和,然后分别与当前最大值相比较,若是最大的就保存。如果某子段和小于0,则计算下一个子段。下一个子段是从上一个子段的终结元素开始计算的。以下为代码(VC++6.0运行通过):
#include<iostream>
#include <limits>
using namespace std;
const int min=INT_MIN ;//int的底线
const int num=10;
const int test[num]={-10,-2,3,4,5,3,-3,4,-2,-11};//待测数组
int MaxSubsum(int n,const int *a) //动态规划实现求最大字段的函数
{
int sum=min; //应对数组全为负数时
int b=0;
for(int i=1;i<n;i++)
{
if(b>0) b +=a[i];
else b=a[i]; //求解各子问题
// cout<<b<<" "<<a[i]<<endl;
if(b>sum)sum=b; //保存当前最优解
}
return sum;
}
int main()
{
cout<<MaxSubsum(num,test)<<endl;
return 0;
}
怎么使用动态规划算法对于我这个初学者很难,但是怎么证明一个问题可以用动态规划算法求解,这个更难!只是看看书上的例子明白是这么一回事,没看例子之前,很难想到用什么算法去求解。有待进一步学习。