• 最大连续子序列(经典DP)


    最大连续子序列 Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u

    Description

    给定K个整数的序列{ N1, N2, ..., NK },其任意连续子序列可表示为{ Ni, Ni+1, ...,
    Nj },其中 1 <= i <= j <= K。最大连续子序列是所有连续子序列中元素和最大的一个,
    例如给定序列{ -2, 11, -4, 13, -5, -2 },其最大连续子序列为{ 11, -4, 13 },最大和
    为20。
    在今年的数据结构考卷中,要求编写程序得到最大和,现在增加一个要求,即还需要输出该
    子序列的第一个和最后一个元素。
     

    Input

    测试输入包含若干测试用例,每个测试用例占2行,第1行给出正整数K( < 10000 ),第2行给出K个整数,中间用空格分隔。当K为0时,输入结束,该用例不被处理。
     

    Output

    对每个测试用例,在1行里输出最大和、最大连续子序列的第一个和最后一个元
    素,中间用空格分隔。如果最大连续子序列不唯一,则输出序号i和j最小的那个(如输入样例的第2、3组)。若所有K个元素都是负数,则定义其最大和为0,输出整个序列的首尾元素。
     

    Sample Input

    6 -2 11 -4 13 -5 -2 10 -10 1 2 3 4 -5 -23 3 7 -21 6 5 -8 3 2 5 0 1 10 3 -1 -5 -2 3 -1 0 -2 0
     

    Sample Output

    20 11 13 10 1 4 10 3 5 10 10 10 0 -1 -2 0 0 0

    Hint

    Hint
    Huge input, scanf is recommended.
    设一数组mx,mx[i]含义:所有以a[i]为结尾的序列的序列和构成一个集合,此集合的最大值就是mx[i]
    如1,2,3.所有以a[2]=3为结尾的序列的序列和集合是{6,5,3},因而mx[2]=6.
    mx的状态转移方程:mx[i] = max{mx[i-1]+a[i], a[i]}
    ans必定是mx[0···(k-1)]之一。由于要记录起始位置和结束位置,引入s数组记录获得mx的序列的起始元素的位置,而由mx的定义,mx[i]的结束位置是i不用记录。
     
     1 #include <iostream>
     2 #include <string>
     3 #include <set>
     4 #include <map>
     5 #include <vector>
     6 #include <stack>
     7 #include <queue>
     8 #include <cmath>
     9 #include <cstdio>
    10 #include <cstring>
    11 #include <algorithm>
    12 using namespace std;
    13 #define LL long long
    14 #define cti const int
    15 #define ctll const long long
    16 #define dg(i) cout << "*" << i << endl;
    17 
    18 struct Seq
    19 {
    20     int sum, s;
    21 }mx[10005];
    22 int a[10005];
    23 int k;
    24 
    25 int main()
    26 {
    27     while(scanf("%d", &k) && k)
    28     {
    29         bool tag = false;
    30         for(int i = 0; i < k; i++)
    31         {
    32             scanf("%d", &a[i]);
    33             if(a[i] >= 0) tag = true;
    34         }
    35         if(!tag)
    36         {
    37             printf("%d %d %d\n", 0, a[0], a[k-1]);
    38             continue;
    39         }
    40         int ans = 0;
    41         mx[0].sum = a[0], mx[0].s = 0;
    42         for(int i = 1; i < k; i++)
    43         {
    44             if(mx[i-1].sum >= 0)
    45             {
    46                 mx[i].sum = mx[i-1].sum + a[i];
    47                 mx[i].s = mx[i-1].s;
    48                 if(mx[ans].sum < mx[i].sum)
    49                     ans = i;
    50             }
    51             else
    52             {
    53                 mx[i].sum = a[i];
    54                 mx[i].s = i;
    55                 if(mx[ans].sum < mx[i].sum) ans = i;
    56             }
    57         }
    58         printf("%d %d %d\n", mx[ans].sum, a[mx[ans].s], a[ans]);
    59     }
    60     return 0;
    61 }
  • 相关阅读:
    [LeetCode] Implement Queue using Stacks 用栈来实现队列
    [LeetCode] Power of Two 判断2的次方数
    [LeetCode] 230. Kth Smallest Element in a BST 二叉搜索树中的第K小的元素
    cvReleaseImage 释放内存出错
    FlyCapture2 fc2Image OpenCV IplImage Conversion 两种图像格式之间的转换
    FlyCapture2 Qt5 MinGW Configuration
    [LeetCode] 14. Longest Common Prefix 最长共同前缀
    [LeetCode] 19. Remove Nth Node From End of List 移除链表倒数第N个节点
    [LeetCode] 229. Majority Element II 求大多数之二
    [LeetCode] 23. Merge k Sorted Lists 合并k个有序链表
  • 原文地址:https://www.cnblogs.com/cszlg/p/2941372.html
Copyright © 2020-2023  润新知