給定乙個陣列a[a0,a1,a2,...,an],求陣列中 連續子段之和 的最大值。
(1)最簡單的演算法:窮舉法
計算所有的連續子段之和,得出最大值
// 窮舉法:計算所有的子串行和
// o(n^3)
public static int maxsum1(int data)
max = tmp > max ? tmp : max;
} }return max;
}
(2) 窮舉法改進版
去除
for (int k = i; k <= j; k++)
是的演算法複雜度減為o(n^2)
// maxsum2的改進版
// o(n^2)
public static int maxsum2(int data)
} return max;
}
(3) 動態規劃
/**
* m[j] = max(a[i]+a[i+1]+...+a[j]) i : 0~j
* m[j] = m[j-1]+a[j] m[j-1]>=0
* = a[j] m[j-1]<0
* max = max(m[j]) j : 0~n
* m[j]是最後一項為a[j]的0~j之間的最大子段和,m的最大值即為最大子段和
* o(n)
*/public static int maxsum3(int data) else
} int max = m[0];
for (int j = 1; j < m.length; j++)
return max;
}
+最優子結構
整個陣列的最大子項和,一定包含子陣列的最大子項和。max(m[j])
+建立遞迴關係
自頂向下,建立遞迴關係,至最原子態的問題.
m[j] = m[j-1]+a[j] m[j-1]>=0
= a[j] m[j-1]<0
+自底向上,計算各個子問題的最優解
由最原子態的問題(m[0]=data[0])的最優解開始,構建全部子問題的最優解,並記錄過程
+求解整個問題的最優解
由全部子問題的最優解,自頂向下,組合出整個問題的最優解
比較得出m的最大值。
(4)動態規劃的改進版
/**
* * max 1 1 4 14 14 16 20 26 36 36
* tmp 1 -1 4 14 11 16 20 26 36 6
* maxsum3的改進版,maxsum3中在最後尋找最大值,可改為在迴圈過程中只儲存m的最大值
*/public static int maxsum(int data) else
if (max < tmp)
} return max;
}
動態規劃 最大子段和
題目描述 給出一段序列,選出其中連續且非空的一段使得這段和最大。輸入輸出格式 輸入格式 第一行是乙個正整數nn,表示了序列的長度。第二行包含n個絕對值不大於10000的整數a i,描述了這段序列。輸出格式 乙個整數,為最大的子段和是多少。子段的最小長度為1。輸入輸出樣例 輸入樣例 1 72 4 3 ...
動態規劃 最大子段和
動態規劃 最大子段和 lyk喜歡幹一些有挑戰的事,比如說求區間最大子段和。它知道這個題目有o n 的做法。於是它想加強一下。也就是說,lyk一開始有n個數,第i個數字是ai,它找來了乙個新的數字p,並想將這n個數字中恰好乙個數字替換成p。要求替換後的最大子段和盡可能大。lyk知道這個題目仍然很簡單,...
動態規劃 最大子段和
最大子段和是乙個十分經典的問題。給定由n個整數 包含負整數 組成的序列a1,a2,an,求該序列子段和的最大值。當所有整數均為負值時定義其最大子段和為0。例如,當 a1,a2,a7,a8 1,3,7,8,4,12,10,6 時,最大子段和為 23 bj是1到j位置的最大子段和 a1a2 ai aj ...