• [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:
    %d %d %d
    ", index + 1, gSum, gLow, gHigh);
    102 
    103         if (index != N - 1)
    104             printf("
    ");
    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:
    ",times);
    35         printf("%d %d %d
    ",max,pre_x+1,pre_y+1);
    36         if(nums>0)printf("
    ");
    37         times++;
    38     } 
    39     return 0;
    40 }
  • 相关阅读:
    简单的JAVAWeb选课系统
    公文流转系统001
    第九周动手动脑
    JAVA文件操作
    动手动脑-异常处理
    个人NABCD
    水王(课堂作业)
    软件学习进度表07
    软件工程学习进度表06
    软件工程个人作业05(二维数组求最大子数组的和)
  • 原文地址:https://www.cnblogs.com/night-ride-depart/p/4521100.html
Copyright © 2020-2023  润新知