題目鏈接:http://acm.hdu.edu.cn/showproblem.php?pid=1003 1003是喜聞樂見的最大連續子串和,經典的動態規劃題目,經典歸經典,我確實是剛剛做……在這道題中,我們需要保證的是在計算過程之中,計算的和是一直增加的,如果碰到了讓和減少的元素,直接把和更新為0,并且更新臨時首指針,每找到一個更優的解,把真正的首指針和尾指針更新,整個過程中一直保證的是和是遞增的。注意我說的是非全負的情況。
 view code 1 #include <cstdio> 2 int sum, s, t, ss, maxn, a[100100]; 3 bool f; 4 int main(){ 5 int t, n, p; 6 scanf("%d", &p); 7 for (int k = 1; k <= p; k++){ 8 scanf("%d", &n); 9 f = 0, maxn = -9999999; sum = 0; 10 for (int i = 1; i <= n; i++){ 11 scanf("%d", &a[i]); 12 if (a[i] >= 0) f = 1; 13 } 14 if (!f){ 15 for (int i = 1; i <= n; i++) 16 if (a[i] > maxn){ 17 maxn = a[i]; 18 s = i; 19 } 20 printf("Case %d:\n%d %d %d\n", k, maxn, s, s); 21 } 22 else{ 23 s = 1; t = 1; ss = 0; 24 for (int i = 1; i <= n; i++){ 25 sum += a[i]; 26 if (sum < 0){ 27 ss = i; 28 sum = 0; 29 } 30 else if (sum > maxn){ 31 maxn = sum; 32 s = ss + 1; 33 t = i; 34 } 35 } 36 printf("Case %d:\n%d %d %d\n", k, maxn, s, t); 37 } 38 if (k < p) printf("\n"); 39 } 40 return 0; 41 題目鏈接: http://acm.hdu.edu.cn/showproblem.php?pid=1024 這道題厲害了,要求在n個數里面求m個最大子段和,要求最終的和最大,其實就是計算m次,因為這此不用記錄區間的首尾元素,所以其實比上一道題好寫一些。
 view code 1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 using namespace std; 5 const int maxn = 1000100; 6 int n, m, ans, a[maxn], f[maxn], g[maxn]; 7 int main(){ 8 while (~scanf("%d%d", &m, &n)){ 9 for (int i = 1; i <= n; i++) scanf("%d", &a[i]); 10 memset(f, 0, sizeof(f)); 11 memset(g, 0, sizeof(g)); 12 for (int i = 1; i <= m; i++){ 13 ans = -100 * maxn; 14 for (int j = i; j <= n; j++){ 15 f[j] = max(f[j - 1], g[j - 1]) + a[j]; 16 g[j - 1] = ans; 17 ans = max(ans, f[j]); 18 } 19 } 20 printf("%d\n", ans); 21 } 22 return 0; 23
|