zoukankan      html  css  js  c++  java
  • Luogu P1115 最大子段和(dp 贪心)

     P1115 最大子段和

    题目描述

    给出一段序列,选出其中连续且非空的一段使得这段和最大。

    输入输出格式

    输入格式:

    输入文件maxsum1.in的第一行是一个正整数N,表示了序列的长度。

    第2行包含N个绝对值不大于10000的整数A[i],描述了这段序列。

    输出格式:

    输入文件maxsum1.out仅包括1个整数,为最大的子段和是多少。子段的最小长度为1。

    输入输出样例

    输入样例#1:
    7
    2 -4 3 -1 2 -4 3
    输出样例#1:
    4

    说明

    【样例说明】2 -4 3 -1 2 -4 3

    【数据规模与约定】

    对于40%的数据,有N ≤ 2000。

    对于100%的数据,有N ≤ 200000。

      可以看出来是一道dp题,转移方程很好找, f[i] = max(f[i-1], 0) + a[i]

      边界条件是f[0] = 0            为什么要和0作比较,因为如果比0小,那么这个字段和活着也是挺失败的,不如重修2333

      AC①: dp(48ms)

     1 #include <cstdio>
     2 #include <algorithm>
     3 
     4 int a[200005];
     5 int f[200005];
     6 
     7 int main()
     8 {
     9     int n;
    10     scanf("%d", &n);
    11     for(int i=1; i<=n; i++)
    12         scanf("%d", &a[i]);
    13     
    14     for(int i=1; i<=n; i++)
    15         f[i] = std::max(f[i-1], 0) + a[i];
    16     
    17     int maxx = -1234567;
    18     for(int i=1; i<=n; i++)
    19             if(f[i] > maxx)
    20                 maxx = f[i];
    21     
    22     printf("%d", maxx);
    23     return 0;
    24 }

      还可以用贪心的思路做

      AC②: (贪心 36ms)

     1 #include <cstdio>
     2 
     3 int main()
     4 {
     5     int n, a, b, maxx;
     6     scanf("%d", &n);
     7     b = maxx = -1234567;    // b表示前几个字段和最大值
     8     for(int i=1; i<=n; i++)
     9     {
    10         scanf("%d", &a);
    11         if(b < 0)    b = a;    // 如果b<0 那么不如直接重开
    12         else b += a;    // b>=0 说明前面的字段和比较大 可以继续加下去
    13         if(b > maxx) maxx = b;
    14     }
    15     printf("%d", maxx);
    16     return 0;
    17 }
  • 相关阅读:
    转场动画3-手势返回
    UITableViewCell的选中时的颜色设置
    git的使用
    MarkDown语法学习笔记
    移动作业
    移动开发音乐播放器
    python循环删除list中的元素
    Linux权限管理
    Linux用户和用户组
    数据库常用基础操作
  • 原文地址:https://www.cnblogs.com/yBaka/p/7397260.html
Copyright © 2011-2022 走看看