子数组最大值设计01
设计思路:
本次二柱子的阴影终于不在笼罩我了,我开始在老师的带领下,做新新一轮的挑战,下面是新任务的大致意思:
输入一个整形数组,数组里有正数也有负数。数组中连续的一个或多个整数组成一个子数组,每个子数组都有一个和,求最大子数组的和。(要求解法的复杂度为(n))
题目进本清楚了,我一看顿感似曾相识过,想了半天,就想了出了平常的n^3的循环找每个子数组的最大值这样的没用AC方式,再仔细想想把每次循环优化最多到n^2,再想想复杂度高的问题所在就是因为在每次循环时有大量重复的比较,这样就要考虑递归了。等到这里,以前一起ac的队友已经搞定了,而且告诉大家是动态规划问题,我感到自己还是差劲啊,虽然研究过背包问题等等,落实不到实际问题啊,不说了,把简单算法思想写上;
解题过程
数组形式:a[0],a[1],a[2],a[3]........a[n-1],a[n]
总共可以看成求子过程最优,共两种情况:
把b[]=max(a[0]+a[1]+...a[i-1])看成到i元素的(i-1)子数组最大值
If(b[]<0)这样a[i]+b[]<a[i] 则最大换为a[i]
If(b[]>=0)a[i]+b[]>a[i] 最大换为a[i]+b[]
代码:
1 /* 2 求子数组的和 3 输入整形数组,数组里有正数有负数,连续数字构成子数组 4 求子数组最大值O(n) 5 */ 6 #include<iostream> 7 using namespace std; 8 9 int main() 10 { 11 12 //解题用动态规划求最优子结构 13 14 cout<<"请输入数组元素个数:"<<endl; 15 int num; //数组元素个数 16 cin>>num; 17 cout<<"请输入数组元素:"<<endl; 18 int a[100]={0}; 19 for(int i=0;i<num;i++) 20 cin>>a[i]; //输入数组元素 21 22 //考虑首尾相连时改变数组结束判断的位置 23 24 //动态求解 25 int b[100][100]; 26 b[0][0]=0; //初始子数组和 27 b[0][1]=a[0]; //a[i]数的值 28 for(int i=1;i<num;i++) 29 { 30 if(b[i-1][0]>=0) 31 b[i][0]=b[i-1][0]+b[i-1][1]; 32 else 33 b[i][0]=b[i-1][1]; 34 b[i][1]=a[i]; 35 } 36 //加上最后一个数的判断 37 if(b[num-1][0]>=0) 38 b[num][0]=b[num-1][0]+b[num-1][1]; 39 else 40 b[num][0]=b[num-1][1]; 41 //比较各个子数组最大的求出值 42 int max=b[0][0]; 43 for(int i=1;i<=num;i++) 44 { 45 if(b[i][0]>max) 46 max=b[i][0]; 47 } 48 cout<<"子数组和最大值为:"<<max<<endl; 49 return 0; 50 }
运行截图:
求解总结
解题过程是一个需要转换为数学模型的过程,算法很重要,算法很重要,算法很重要。重要的事说三遍。所以算法以后自己遇到就必须自己想办法去实现。加油吧,小逸
Ps:同组的另一战友的博客
http://www.cnblogs.com/brucekun/p/5316601.html
每日一小步,月过一大步~~加油