[hdu 1003] Max Sum

跟<算法导论(第三版)>上的一样,抄下来的

30 - 60 ms

标准的分治策略

复制代码
  1 #include <stdio.h>
  2 
  3 int A[100000], Lenght;
  4 const int NegativeInfinity = -1000000;
  5 
  6 int gLow, gHigh, gSum;
  7 
  8 void FindMaxCrossingSubArray(int low, int mid, int high)
  9 {
 10     int left_sum = NegativeInfinity;
 11     int sum = 0;
 12     int max_left = mid;
 13     for (int i = mid; low <= i; i--)
 14     {
 15         sum += A[i];
 16         if (sum >= left_sum)
 17         {
 18             left_sum = sum;
 19             max_left = i;
 20         }
 21     }
 22 
 23     int right_sum = NegativeInfinity;
 24     sum = 0;
 25     int max_right = mid + 1;
 26     for (int i = mid + 1; i <= high; i++)
 27     {
 28         sum = sum + A[i];
 29         if (sum > right_sum)
 30         {
 31             right_sum = sum;
 32             max_right = i;
 33         }
 34     }
 35 
 36     gLow = max_left;
 37     gHigh = max_right;
 38     gSum = left_sum + right_sum;
 39 }
 40 
 41 void FindMaxSubArray(int low, int high)
 42 {
 43     if (low == high)
 44     {
 45         gLow = low;
 46         gHigh = high;
 47         gSum = A[low];
 48         return;
 49     }
 50     
 51     int mid = (high + low) / 2;
 52     FindMaxSubArray(low, mid);
 53     int left_low = gLow, left_high = gHigh, left_sum = gSum;
 54 
 55     FindMaxSubArray(mid + 1, high);
 56     int right_low = gLow, right_high = gHigh, right_sum = gSum;
 57 
 58     FindMaxCrossingSubArray(low, mid, high);
 59     int cross_low = gLow, cross_high = gHigh, cross_sum = gSum;
 60 
 61     if (left_sum >= right_sum && left_sum >= cross_sum)
 62     {
 63         gLow = left_low;
 64         gHigh = left_high;
 65         gSum = left_sum;
 66     }
 67     else if (cross_sum >= right_sum && cross_sum >= left_sum)
 68     {
 69         gLow = cross_low;
 70         gHigh = cross_high;
 71         gSum = cross_sum;
 72     }
 73     else
 74     {
 75         gLow = right_low;
 76         gHigh = right_high;
 77         gSum = right_sum;
 78     }
 79 }
 80 
 81 int main()
 82 {
 83     int N;
 84     scanf("%d", &N);
 85 
 86     for (int index = 0; index < N; index++)
 87     {
 88         // input
 89         int number;
 90         scanf("%d", &number);
 91 
 92         for (int i = 1; i <= number; i++)
 93         {
 94             scanf("%d", A + i);
 95         }
 96 
 97         // find
 98         FindMaxSubArray(1, number);
 99 
100         // output
101         printf("Case %d:\n%d %d %d\n", index + 1, gSum, gLow, gHigh);
102 
103         if (index != N - 1)
104             printf("\n");
105     }
106 
107     return 0;
108 }
复制代码

 

网上大神的

来源: http://acm.hdu.edu.cn/discuss/problem/post/reply.php?postid=23376&messageid=1&deep=0

15 ms 的光景

关键是 最大子数组一定是在一个负号之前

复制代码
 1 #include <stdio.h>
 2 #include <stdlib.h>
 3 
 4 
 5 /* run this program using the console pauser or add your own getch, system("pause") or input loop */
 6 
 7 int main(int argc, char *argv[]) {
 8     int length;
 9     int Num[100000];
10     int nums,i,times=1;
11     int sum,pre_x,x,pre_y,y,max;
12     scanf("%d",&nums);
13     while(nums-->0){
14         sum=0;max=0;
15         pre_x=0;pre_y=0;x=0;y=0;
16         scanf("%d",&length);
17         for(i=0; i<length; i++){
18             scanf("%d",&Num[i]);
19         }
20         max=Num[0];
21         for(i=0; i<length; i++){
22             sum+=Num[i];
23             
24             if(Num[i]>0)y=i;
25             if(sum>max){
26                 pre_x=x;
27                 pre_y=y;
28                 max=sum;
29             }
30             if(sum<0){
31                 sum=0;x=i+1;y=i+1;
32             }
33         }
34         printf("Case %d:\n",times);
35         printf("%d %d %d\n",max,pre_x+1,pre_y+1);
36         if(nums>0)printf("\n");
37         times++;
38     } 
39     return 0;
40 }
复制代码

 

本文作者:endlesstravel

本文链接:https://www.cnblogs.com/night-ride-depart/p/4521100.html

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   endlesstravel  阅读(409)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示
💬
评论
📌
收藏
💗
关注
👍
推荐
🚀
回顶
收起