求解PTA最大子列和问题的三种方法(包括输出首尾项)

来源:互联网 发布:qq邮箱for mac 编辑:程序博客网 时间:2024/05/19 20:42

01-复杂度1 最大子列和问题(20 分)

给定个整数组成的序列{ , ...,  },“连续子列”被定义为{ , ...,  },其中 。“最大子列和”则被定义为所有连续子列元素的和中最大者。例如给定序列{ -2, 11, -4, 13, -5, -2 },其连续子列{ 11, -4, 13 }有最大的和20。现要求你编写程序,计算给定整数序列的最大子列和。

本题旨在测试各种不同的算法在各种数据情况下的表现。各组测试数据特点如下:

  • 数据1:与样例等价,测试基本正确性;
  • 数据2:102个随机整数;
  • 数据3:103个随机整数;
  • 数据4:104个随机整数;
  • 数据5:105个随机整数;

输入格式:

输入第1行给出正整数 ();第2行给出个整数,其间以空格分隔。

输出格式:

在一行中输出最大子列和。如果序列中所有整数皆为负数,则输出0。

输入样例:

6-2 11 -4 13 -5 -2

输出样例:

20

#include<iostream>using namespace std;int start, finish;int max_sub(int *a, int size)//O(n^2)优化穷举法求最大子序列和的函数   {int i, j, v;int max = a[0];for (i = 0; i<size; i++){v = 0;for (j = i; j<size; j++){v = v + a[j];         //Sum(i, j+1) = Sum(i, j) + A[j+1]  if (v>max)  max = v;}}return max;}int max_dg(int *a,int size)//O(n)动态规划法求最大子序列和的函数   {int i, sum = 0, maxsum = 0, flag = 0, temp_sum = 0;for (i = 0; i<size; i++)              //在该循环内判断序列中是否存在正数   {if (a[i]>0)flag = 1;       //用flag标记,若存在正数则为1   }if (flag == 0)             //若不存在正数,则输出0和首尾元素{   maxsum = 0; start = 0; finish = size - 1;return 0;}for (i = 0; i<size; i++){temp_sum += a[i];if (temp_sum > maxsum){maxsum = temp_sum; finish = i;}else if (temp_sum<0)temp_sum = 0;}/*由于子序列最大和为maxsum,所以只需将maxsum与前面各项相减到零即可确定第一个元素下标start。由于题目中规定若有不只一组最大子序列和时输出start和finish较小的那一组,所以i要减到0。以防把前面相加等于零的子列忽略。若这里规定的是输出finish-start最小的一组,则在判断sum==0时退出循环即可*/for (i = finish; i >= 0; i--){sum -= a[i];if (sum == 0)start = i;}return maxsum;}int Max_3(int a, int b, int c)     //O(NlogN)分治法求最大子序列和的函数{if (a < b)a = b;if (a < c)return c;elsereturn a;}int MaxSubSeqSum(const int *A, int left, int right){int MaxLeftSum, MaxRightSum, MaxSum;int MaxLeftBorderSum, MaxRightBorderSum;int LeftBorderSum, RightBorderSum;int center;int i;if (left == right){if (A[left] > 0)return A[left];elsereturn 0;}center = (left + right) / 2;MaxLeftSum = MaxSubSeqSum(A, left, center);MaxRightSum = MaxSubSeqSum(A, center + 1, right);MaxLeftBorderSum = 0;LeftBorderSum = 0;for (i = center; i >= left; i--){LeftBorderSum += A[i];if (LeftBorderSum > MaxLeftBorderSum)MaxLeftBorderSum = LeftBorderSum;}MaxRightBorderSum = 0;RightBorderSum = 0;for (i = center + 1; i <= right; i++){RightBorderSum += A[i];if (RightBorderSum > MaxRightBorderSum)MaxRightBorderSum = RightBorderSum;}MaxSum = Max_3(MaxLeftSum, MaxRightSum, MaxLeftBorderSum + MaxRightBorderSum);return MaxSum;}int main(){int i, j;int a[100];cout << "please input a number" << endl;cin >> j;cout << "please input the numbers" << endl;for (i = 0; i < j; i++) //输入进行计算的序列cin >> a[i];cout << "the row is :";for (i = 0; i < j; i++) //输出获得的序列cout <<" " <<a[i];cout << endl;cout << "The sum of biggest row is:"<<max_dg(a,j) << endl; //输出最大子序列和cout << "输出序列的首、尾元素:"<<a[start]<<","<<a[finish]<<endl;/*for (i = 0; i < j; i++)                //生成随机数,并存放在数组中{a[i] = rand();cout << a[i];}cout << endl;*/return 0;}

 
阅读全文
0 0
原创粉丝点击