1 动态规划
1.1 基本思想
动态规划算法与分治法类似,其基本思想也是将待求解问题分解成若干个子问题。
与分治法的区别在于,适用于动态规划算法求解的问题,经分解得到的子问题往往不是互相独立的;若用分治法求解,则分解得到的子问题数目太多,导致最终解决原问题需指数时间。原因在于:虽然子问题的数目常常只有多项式量级,但在用分治法求解时,有些子问题被重复计算了许多次,如果可以保存已解决的子问题的答案,就可以避免大量重复计算,从而得到多项式时间的算法。
动态规划法的基本思路是:构造一张表来记录所有已解决的子问题的答案(无论算法形式如何,其填表格式是相同的)。
1.2 适用条件
适用动态规划的问题必须满足最优化原理和无后效性。
最优化原理(最优子结构性质):
最优化原理可这样阐述:一个最优化策略具有这样的性质,不论过去状态和决策如何,对前面的决策所形成的状态而言,余下的诸决策必须构成最优策略。简而言之,一个最优化策略的子策略总是最优的。一个问题满足最优化原理又称其具有最优子结构性质
无后效性:
将各阶段按照一定的次序排列好之后,对于某个给定的阶段状态,它以前各阶段的状态无法直接影响它未来的决策,而只能通过当前的这个状态。换句话说,每个状态都是过去历史的一个完整总结。这就是无后向性,又称为无后效性。
子问题的重叠性:
动态规划算法的关键在于解决冗余,这是动态规划算法的根本目的。动态规划实质上是一种以空间换时间的技术,它在实现的过程中,不得不存储产生过程中的各种状态,所以它的空间复杂度要大于其他的算法。选择动态规划算法是因为动态规划算法在空间上可以承受,而搜索算法在时间上却无法承受,所以我们舍空间而取时间
2 最大子段和问题描述
给定n个整数(可能为负数)组成的序列a1,a2,…,an。求该序列形如下式的子段和的最大值:
当所有整数均为负整数时定义其最大子段和为0。依次定义,所求的最优值为:
例如:(a1,a2,a3,a4,a5,a6)=(-2,11,-4,13,-5,-2) 该序列的最大子段和为:
3 算法分析
通过对分治算法的分析可知,若记:
则所求的最大子段和为:
由b[j]的定义可知:当时:
否则:
由此可得b[j]的动态规划递归式:
4 C++实现
int maxSubArray(vector<int>& nums) {
int size=nums.size();
int* b = new int[size];
b[0]=nums.at(0);
for(int i=1;i if(b[i-1]<0){
b[i]=nums.at(i);
}else{
b[i]=b[i-1]+nums.at(i);
}
}
int maxV=b[0];
for(int i=0;i if(maxV maxV=b[i];
}
}
return maxV;
}
![a16eb30d4b2c9497750ae79e4c091b54.png](https://i-blog.csdnimg.cn/blog_migrate/c967ea340627961453b0cae7bc192a93.png)