算法设计-动态规划(1)
子序列和最大问题
- 子序列和最大
递推方程:d[i] = max{a[i], d[i-1]+a[i]},d[i]表示的是子序列一定会包含第i个元素的最大和,要么是从a[i]开始,要么是在原来的最大序列上再添一个a[i]。最终得到的最大子序列和是max{d[i]}(0<=i<=n)
代码如下:
//b[i]的状态转移方程:b[i]=max{b[i-1]+a[i],a[i]}。最终我们得到的最大子段和为max{b[i], 0<=i<n}
int findmax(int arr[], int n) {
int maxvalue = -200, temp = 0;
for(int i=0; i<n; i++) {
if(temp > 0) {
temp += arr[i]; //这里是用前i个数和第i个数进行比较,如果前i-1个数已经大于0,那么肯定是前i个数的和大于第i个数
}
else temp = arr[i]; //以上是一定包含第i个数的最大值
if(temp > maxvalue) {
maxvalue = temp;
}
}
return maxvalue;
}
-
子序列和的绝对值最大
现求子序列的最大和,再求子序列的最小和,之后两者比较一下 -
子序列的积最大
维护两个数组,一个是最大值,一个是最小值,在遍历到下一个元素的时候,分别都要记录最大值和最小值(防止负负得正之后出现了最大值) -
两段重合不连续子序列最大和
要维护两个数组,一个是从前向后记录最大值,一个是从后向前记录最大值,然后把这两个数组的和相加找一个最大值
int solve(int arr[], int n) {
int dp[Max], lt[Max], rt[Max], maxvalue;
dp[0] = lt[0] = dp[n+1] = rt[n+1] = maxvalue = -INF;
for(int i=1; i<=n; i++) {