package edu.pku.ss.hlj;
public class MaxSubSumRec
{
/**
* 分治法求最大子段和
* @param a
* @param left
* @param right
* @return
*/
private static int maxSumRec(int[] a, int left, int right)
{
if (left == right)
{
if (a[left] > 0)
{
System.out.print(a[left]+" ");
return a[left];
}
else
{
return 0;
}
}
int center = (left + right) / 2;
int maxLeftSum = maxSumRec(a, left, center);
int maxRightSum = maxSumRec(a, center + 1, right);
int maxLeftBorderSum = 0;
int leftBorderSum = 0;
for (int i = center; i >= left; i--)
{
leftBorderSum += a[i];
if (leftBorderSum > maxLeftBorderSum)
{
maxLeftBorderSum = leftBorderSum;
}
}
int maxRightBorderSum = 0;
int rightBorderSum = 0;
for (int i = center + 1; i <= right; i++)
{
rightBorderSum += a[i];
if (rightBorderSum > maxRightBorderSum)
{
maxRightBorderSum = rightBorderSum;
}
}
return max(maxLeftSum, maxRightSum, maxRightBorderSum + maxLeftBorderSum);
}
//入口程序
public static int maxSubSum(int[] a)
{
return maxSumRec(a, 0, a.length - 1);
}
//求三数中的最大值
private static int max(int a, int b, int c)
{
int max = a > b ? a : b;
max = c > max ? c : max;
return max;
}
private static int max(int a,int b){
int max = a>b?a:b;
return max;
}
private static int min(int a,int b,int c){
int min = a<b?a:b;
min = min<c?min:c;
return min;
}
/**
* 动态规划方法一
* @param a
* @return
*/
public static int maxSubSum2(int[] a)
{
int maxSum = 0;
int thisSum = 0;
for (int j = 0; j < a.length; j++)
{
thisSum += a[j];
if (thisSum > maxSum)
{
maxSum = thisSum;
}
else if (thisSum < 0)
{
thisSum = 0;
}
}
return maxSum;
}
/**
* 动态规划方法二
* @param a
* @return
*/
public static int maxSubSum3(int[] a){
int maxSum = 0;
int thisSum = 0;//记录前一个最大是子段和C[i]=max{c[i-1]+a[i],a[i]}
for(int i=0;i<a.length;i++){
if(thisSum >0){
thisSum += a[i];
}else{
thisSum = a[i];
}
if(thisSum > maxSum){
System.out.print(a[i] + " ");
maxSum = thisSum;
}
}
return maxSum;
}
/**
* 动态规划方法三
* @param a
* @return
*/
public static int maxS(int[] a){
int[] max = new int[25];
max[0] = a[0];
int maxSum = max[0];
for(int i=1;i<a.length;i++){
max[i] = max(max[i-1]+a[i],a[i]);
if(maxSum < max[i]){
maxSum = max[i];
}
}
return maxSum;
}
/**
* 最大子段积(动态规划)
* @param a
*/
public static void multip(int[] a){
int[] min = new int[256];//记录到目前位置为止,最小的负数
int[] max = new int[256];//记录到目前位置为止,最大的正数
max[0] = a[0];//设置为第一个数值
min[0] = a[0];
int max_val = max[0];//记录最大乘积
for(int i=1;i<a.length;i++){
max[i] = max(max[i-1]*a[i],min[i-1]*a[i],a[i]);
min[i] = min(max[i-1]*a[i],min[i-1]*a[i],a[i]);//a[i]正负数都在这里了
if(max_val < max[i]){
max_val = max[i];
}
}
if(max_val < 0){
System.out.println(-1);
}else{
System.out.println(max_val);
}
}
public static void main(String[] args)
{
int[] a = {1,-2, 11, -4, 13, -5, -2};
int[] b = {1, -3,-2,-2, -3,0,8,5};
// System.out.println(MaxSubSumRec.maxSubSum(a));
// System.out.println(maxSubSum3(a));
System.out.println(maxS(b));
// multip(b);
}
}
最大子段和最大子段积java实现
最新推荐文章于 2023-04-18 21:09:07 发布