最大子段和——动态规划是如何运作的
最大子段和:
给定n个整数(可能为负数)组成的序列a[1],a[2],a[3],…,a[n],求该序列如a[i]+a[i+1]+…+a[j]的子段和的最大值。当所给的整数均为负数时,定义子段和为0。
输入格式:
输入有两行:
第一行是n值(1<=n<=10000);
第二行是n个整数。
输出格式:
输出最大子段和。
输入样例:
在这里给出一组输入。例如:
6
-2 11 -4 13 -5 -2
输出样例:
在这里给出相应的输出。例如:
20
如何使用动态规划寻找最大子段和呢?我们首先需要找到最优子结构。
设序列a[1]、a[2]、···、a[n]为输入序列。则最大子段和可以表示为:
我们另设序列b[1]、···、b[n],其中b[j]表示从a[1]至a[j]的最大子段和。那么
考虑b[j]的性质,可以得出结论:
下面我给出示例代码:
#include <bits/stdc++.h>
#define M INT_MAX
using namespace std;
int findMax(int *data,int lenth){
int bj = 0,finaldata = -M;
for(int i = 0;i < lenth;i++){
if(bj > 0)
bj += data[i];
else bj = data[i];
if(bj > finaldata)
finaldata = bj;
}
return finaldata;
}
int main(){
int lenth,flag = 0;
cin>>lenth;
int *data = new int [lenth];
for(int i = 0;i < lenth;i++){
cin>>data[i];
if(data[i] > 0) flag = 1;
}
if(flag) cout<<findMax(data,lenth);
else cout<<'0';
}
int findMax(int *dataSum,int *data,int lenth){
for(int i = 1;i < lenth;i++){
dataSum[i] = dataSum[i - 1] + data[i];
}
int themax = -M;
for(int i = 0;i < lenth;i++)
for(int j = i + 1;j < lenth;j++){
themax = max(themax,dataSum[j]-dataSum[i]);
}
return themax;
}
int findMax(int *data,int lenth){
int prodata = 0,finaldata = -M;
for(int i = 0;i < lenth;i++){
prodata = max(prodata + data[i],data[i]);
if(prodata > finaldata)
finaldata = prodata;
}
return finaldata;
}
其中下划线代码是选择剔除,斜体代码是筛选最大子段和。
比较第一段和这一段代码,我们会发现,其实这两段代码的差别不大,思想上也是极为相近的,可以理解为一个算法的不同理解。其实算法最重要的也就是思考角度。如果你有一个清晰的解题思路,那么其实动态规划是什么你也不必过多考虑。
如果你看到了这里,说明你仍在试图寻找自己感兴趣的东西,马上就给!
ちびパイア ~吸血姉妹とエッチでビッチな
食用建议:
1.食用地点:PC
2.食材提醒:拔作
3.风格:日常、loli、吸血鬼
传输门:小吸血鬼