1. 程式人生 > >動態規劃——連續子序列最大和

動態規劃——連續子序列最大和

題目描述:
輸入一個整型陣列,數組裡有正數也有負數。
陣列中連續的一個或多個整陣列成一個子陣列,每個子陣列都有一個和。
求所有子陣列的和的最大值。要求時間複雜度為O(n)。

例如輸入的陣列為1, -2, 3, 10, -4, 7, 2, -5,和最大的子陣列為3, 10, -4, 7, 2,
因此輸出為該子陣列的和18。

子問題為以當前元素結尾的序列最大和

//遞迴方法:任何遞推公式都能轉化為遞迴.
	public int maxSum(int []data,int n)
	{
		if(n==0)
			return data[0];
		if(maxSum(data,n-1)<=0)
			return data[n];
		else
			return maxSum(data,n-1)+data[n];
	}
//自頂向下記憶化方法
//用一個數組存放計算的值;
	public int []b=new int[]{-100,-100,-100,-100,-100,-100,-100,-100,-100,-100};
	public int maxSum1(int []data,int n)
	{
		if(n==0)
		{
			b[0]= data[0];
			return b[0];
		}
		if(b[n-1]==-100)//用陣列記憶化的方法!!!!!!
		{
			b[n-1]=maxSum(data,n-1);
		}
		if(b[n-1]<=0)
		{
			b[n]=data[n];
		}
		else
		{
			b[n]=b[n-1]+data[n];
		}
			return b[n];
    }
//DP_自底向上的方法;index存放最大和子序列的首末下標。
		public void  maxSum_DP(int []data,int n,int []index)
		{
			int start=0;
			int end=0;
			int temp=0;
			int maxsum=0;
			int []b=new int [data.length];
			b[0]=data[0];//第一個為他自己,因前邊沒有數,不能放入遞推公式中;
			for(int i=0;i<n-1;i++)
			{
				if(b[i]<=0)
				{
					b[i+1]=data[i+1];
					//只有此時才更新temp
					temp=i+1;
				}
				else
					b[i+1]=b[i]+data[i+1];
				//更新座標;
				if(b[i+1]>maxsum)
				{
					maxsum=b[i+1];
					start=temp;
					end=i+1;
				}
			}
			index[0]=start;
			index[1]=end;
		}