浙大DS_2021秋_Maximum Subsequence Sum

先附上原题

1.使用在线处理算法,成功运行

#include<iostream>
using namespace std;

void SumArray4(int* num, int k, int& L, int& R, int& max, int& t) {
	L = 0;
	int sum = 0;
	int L0 = 0;
	int k0 = 0;
	for (int i = 0; i < k; i++) {
		//第一个0的位置记录
		if (num[i] == 0 && k0==0) {
			t = i;
			k0 = 1;
		}
		sum += num[i];
		if (max < sum) {
			//当sum值大于前一个max,可以更新L的值了
			L = L0;
			R = i;
			max = sum;
		}
		else if (sum < 0) {
			//该处i的num值为负,故取其下一位
			//不可以直接给L赋值,因为无法判定max值与此刻的sum谁更大
			L0 = i + 1;
			sum = 0;
		}
	}
}

int main() {
	int k = 0;
	cin >> k;
	int L = 0, R = 0, max = 0;
	int* num = new int[k];
	for (int i = 0; i < k; i++) {
		cin >> num[i];
	}
	int t = -1;    //测试点5的0位置记录
	SumArray4(num, k, L, R, max, t);
	if (max == 0 && t == -1) {
		L = 0;
		R = k - 1;
	}
	//测试点5:负数和0同时存在,此时不可以按均为负数处理,下标为第一个0的位置
	else if (max == 0 && t != -1) {
		L = t;
		R = t;
	}
	//注意:输出的是num值,不是元素下标
	cout << max << " " << num[L] << " " << num[R] << endl;
	delete[] num;
}

2.第一次尝试解题时,使用的是分治法 - 程序03

出现多个错误,分治时返回值的先后顺序影响最终结果 

有空再写吧,都是最头疼的小测试点

#include<iostream>
using namespace std;

//全局变量 最终下标
//int* MaxR=&R;
//int* MaxL=NULL;

int max3(int a, int b, int c) {
	return a > b ? a > c ? a : c : b > c ? b : c;
}

//使用递归,一层层返回下标值
//MaxR1左边  MaxR2右边  MaxR3中间
int SumArray3(int* num, int left, int right, int& MaxR, int& MaxL) {
	int MaxLeftSum, MaxRightSum;
	int MaxLeftBorderSum = 0, MaxRightBorderSum = 0;
	int LeftBorderSum = 0, RightBorderSum = 0;
	int center;
	int a, b;

	if (left == right) {
		if (num[left] > 0) {
			return num[left];
		}
		else {
			return 0;
		}
	}

	center = (left + right) / 2;

	//考虑全局变量
	int MaxR1 = 0, MaxL1 = 0;  //左
	int MaxR2 = 0, MaxL2 = 0;  //右
	int MaxR3 = 0, MaxL3 = 0;  //中

	MaxR2 = right;
	MaxL2 = center + 1;
	a = SumArray3(num, center + 1, right, MaxR, MaxL);
	MaxRightSum = a;
	MaxR1 = center;
	MaxL1 = left;
	b = SumArray3(num, left, center, MaxR, MaxL);
	MaxLeftSum = b;

	//必须让右边在前,不然会导致下标输出顺序有误

	/*MaxR1 = center;
	MaxL1 = left;
	MaxLeftSum = SumArray3(num, left, center, MaxR, MaxL);
	MaxR2 = right;
	MaxL2 = center + 1;
	MaxRightSum = SumArray3(num, center + 1, right, MaxR, MaxL);*/


	for (int i = center; i >= left; i--) {
		LeftBorderSum += num[i];
		if (LeftBorderSum > MaxLeftBorderSum) {
			MaxLeftBorderSum = LeftBorderSum;
			MaxL3 = i;
		}
	}

	for (int i = center + 1; i <= right; i++) {
		RightBorderSum += num[i];
		if (RightBorderSum > MaxRightBorderSum) {
			MaxRightBorderSum = RightBorderSum;
			MaxR3 = i;
		}
	}

	if (MaxRightSum > MaxLeftSum && MaxRightSum > MaxLeftBorderSum + MaxRightBorderSum) {
		MaxR = MaxR2;
		MaxL = MaxL2;
	}
	else if (MaxRightSum < MaxLeftSum && MaxLeftSum > MaxLeftBorderSum + MaxRightBorderSum) {
		MaxR = MaxR1;
		MaxL = MaxL1;
	}
	else if (MaxRightSum < MaxLeftBorderSum + MaxRightBorderSum && MaxLeftSum < MaxLeftBorderSum + MaxRightBorderSum) {
		MaxR = MaxR3;
		MaxL = MaxL3;
	}
	return max3(MaxLeftSum, MaxRightSum, MaxLeftBorderSum + MaxRightBorderSum);
}

int main() {
	int k = 0;
	cin >> k;
	int num[10005] = { 0 };
	for (int i = 0; i < k; i++) {
		cin >> num[i];
	}
	int MaxR = k;
	int MaxL = 0;
	int max = 0;
	max = SumArray3(num, 0, k, MaxR, MaxL);
	

	cout << max << " " << num[MaxL] << " " << num[MaxR];
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值