有关动态规划求解最大子数组和 突然能够get到的思路

之前一直不明白为什么求解最大子数组和时只要sum不小于0,就可以无条件接受后面那个值是一个负数。上课的时候讲的是从后往前探索的思路,我当时就觉得,这样就可以很好地保证我在遇到最坏情况下能够立刻做出最明智的反应,也就是我先判断一下从后面那个数开始的最大子数组和是都>0(此处没有0,因为加不加都无意义,因此归到<0)。我很能理解为什么从后往前是允许的,毕竟如果那个数的最大子数组和还小,如果我接纳它不就说明我被他“污染”了吗?所以只要后面的那个可以为我前面的数加入成为最大子数组里的元素,他就是有意义的,允许加入。

伪代码如下:

 

#include<bits/stdc++.h>
using namespace std;
#define maxn 150

//D表示最大子数组,X表示对输入数组,Rec表示对应最大子数组结束位置 
int D[maxn],X[maxn],Rec[maxn];

void dp(int D[],int X[],int Rec[],int n){
	for(int i=n-1;i>=1;i--){
		if(D[i+1]>0){
			D[i] = X[i]+D[i+1];
			Rec[i]=Rec[i+1];
		}else{
			D[i] = X[i];
			Rec[i]=i;
		}
	}
}

int main(){
	//读入数组
	int n;
	cin>>n;
	for(int i=1;i<=n;i++){
		cin>>X[i];
	} 
	//初始化数组
	D[n] = X[n];
	Rec[n] = n;
	dp(D,X,Rec,n);
	
	//查找解
	int max=D[1];
	int l,r;
	for(int i=2;i<=n;i++) {
		if(max<D[i]){
			max = D[i];
			l=i;
			r=Rec[i];
		}
	}
	cout<<"最长子数组为:";
	for(int i=l;i<=r;i++){
		cout<<X[i]<<" ";
	}
	cout<<endl;
	cout<<"最长子数组和为:"<<max;
	return 0;
}

 

但是后来,我想,能不能从前往后呢?如果前面的那个值总体sum>0,能够为我后面的数的加入最大子数组和元素,那它也是有意义的,允许加入!

def max_child_4(arr):
    result = arr[0]
    sum = arr[0]
    x = 0
    for i in range(1, len(arr)):
        if sum > 0:
            sum += arr[i]
        else:
            sum = arr[i]
            x = i
        if sum > result:
            result = sum
            y = i
    return result

 

所以我觉得,很多时候,我们或许不能够过于关注与自己相近的事物,我们要有一个全局关,去考虑这个大局是否对我有利,而不能仅仅考虑,最靠近我的这个同学做的一些对我不利的事情,是否真的对我没有帮助。可以再抽象地理解成,如果我要得到离我没有那么近的同学对我的好处(他们整体而言是对我有好处的),那我必须要接纳离我最近的那位同学对我的不利,因为我们是一个连起来的关系链,如果为了不受到离我最近的那位同学对我的伤害的话,那也就相当于选择了他给我带来其他关系整体对我的好处了。

人总不能太“贪心“,不能太过于苛求每个人对你做的事情是否有利于你,只要因为他的出现,仍能够让你有所收获(虽没有收获原来那么多),我们不妨也去接受它!如果因为遗憾于之前更大的好处而放弃目前仅有的好处,那其实是一个失败的战者,最终会被生存法则淘汰。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值