前言
本学习学校开了数据结构这么课,但本人感觉一学期没怎么听,基本的一些东西也搞不出来那种,觉得这个假期有必要在考试之前重新预习一遍……
找了找觉得浙大陈越老师讲的网课不错,于是就准备重新跟一遍数据结构的网课。
01-复杂度1 最大子列和问题
#include <stdio.h>
#include <string.h>
int MaxSum1(int A[],int N)
{
int oneSum,maxSum = 0;
int i,j,k;
for(i=0;i<N;i++){ //i为左端
for(j=i;j<N;j++){ //j为右端
oneSum = 0;
for(k=i;k<=j;k++){
oneSum += A[k];
}
if(maxSum < oneSum){
maxSum = oneSum;
}
}
}
return maxSum;
}
int MaxSum2(int A[],int N)
{
int oneSum,maxSum = 0;
int i,j;
for(i=0;i<N;i++){ //i为左端
oneSum = 0;
for(j=i;j<N;j++){ //j为右端
oneSum += A[j]; //相同i,不同j,累计加比较
if(oneSum > maxSum)
maxSum = oneSum;
}
}
return maxSum;
}
int MaxSum4(int A[],int N) //在线处理
{
int oneSum=0;
int maxSum=0;
int i;
for(i=0;i<N;i++){
oneSum += A[i]; //向右侧累加
if(oneSum > maxSum){
maxSum = oneSum;
}else if(oneSum <0){
oneSum = 0; //发现为负,必不可能,归零
}
}
return maxSum;
}
int maxOfThree(int a,int b,int c)
//三者最大
{
return (a>b)?((a>c)?a:c):((b>c)?b:c);
}
int divide(int a[],int left,int right)
{
if(left == right){ //只有一个数字时结束递归
if(a[left]>0)
return a[left];
return 0;
}
int center = (left+right)/2;
int maxLeft = divide(a,left,center);
int maxRight = divide(a,center+1,right);
int i=0;
int maxLeftBorder = 0;
int leftBorder = 0;
for(i=center;i>=left;i--){ //从边界向左
leftBorder += a[i];
if(maxLeftBorder<leftBorder)
maxLeftBorder = leftBorder;
}
int maxRightBorder = 0;
int rightBorder = 0;
for(i=center+1;i<=right;i++){ //边界向右
rightBorder += a[i];
if(maxRightBorder<rightBorder)
maxRightBorder = rightBorder;
}
return maxOfThree(maxLeft,maxRight,maxRightBorder+maxLeftBorder);
}
int MaxSum3(int A[],int n)
{
return divide(A,0,n-1);
}
int main()
{
int list[6] = {-2,11,-4,13,-5,-2};
int max1 = MaxSum1(list,6);
printf("problem 1 = %d\n",max1);
int max2 = MaxSum2(list,6);
printf("problem 2 = %d\n",max2);
int max3 = MaxSum3(list,6);
printf("problem 3 = %d\n",max3);
int max4 = MaxSum4(list,6);
printf("problem 4 = %d\n",max4);
return 0;
}
#problem 1 = 20
#problem 2 = 20
#problem 3 = 20
#problem 4 = 20
四种方法在慕课中都有讲到
此外,PTA中的升级版版本:
Maximum Subsequence Sum
输入:
10
-10 1 2 3 4 -5 -23 3 7 -21
输出:
10 1 4
#include <stdio.h>
#define maxn 10005
#define INF 0x3f3f3f3f
int a[maxn];
int n;
void f() {
int lsLeft=0, right=0, left=0;//lsLeft为临时左下标,left为最大子序列最左边下标,right为最右边下标
int ThisSum=0, MaxSum=-INF;//首先ThisSum代表临时子列和,MaxSum为最大子列和
for (int i = 0; i < n; i++) {
ThisSum += a[i];
if (ThisSum < 0) {
ThisSum = 0;
lsLeft = i+1;//更新临时下标
}
else if (ThisSum > MaxSum) {
MaxSum = ThisSum;
left = lsLeft;//更新左下标
right = i;//右下标
}
}
if (MaxSum < 0) {
printf("0 %d %d", a[0], a[n-1]);
}
else {
printf("%d %d %d", MaxSum, a[left], a[right]);
}
}
int main() {
scanf("%d", &n);
for (int i = 0; i < n; i++) {
scanf("%d", &a[i]);
}
f();
return 0;
}