子串和

时间限制:5000 ms  |  内存限制:65535 KB
难度:3
 
描述
给定一整型数列{a1,a2...,an},找出连续非空子串{ax,ax+1,...,ay},使得该子序列的和最大,其中,1<=x<=y<=n。
 
输入
第一行是一个整数N(N<=10)表示测试数据的组数)
每组测试数据的第一行是一个整数n表示序列中共有n个整数,随后的一行里有n个整数I(-100=<I<=100),表示数列中的所有元素。(0<n<=1000000)
输出
对于每组测试数据输出和最大的连续子串的和。
样例输入
1
5
1 2 -1 3 -2
样例输出
5

因为提前知道了要用动态规划思想,所以大大减少了难度。尽管如此,我还是用了两个小时才思考出答案。最后思路是正确的,但是最佳答案是边输入边判断。这样直接就减去了数组存储的过程。
动态规划,关键就是存储小问题的答案,避免重复计算小问题。大问题划分为小问题,这是分治的思想。
这个题的话存在这样一个公式
b[n] = max(a[n] + b[n-], a[n])    when n >
b[] = a[]               when n = 0
子串和的最大值 = 数组b[n]的最大值
#include <stdio.h>
#include <stdlib.h> #define max(a,b) (a>b)?a:b int main()
{
int N;
scanf("%d", &N);
while (N--)
{
int i = , n = , m = , a, b;
scanf("%d", &n); scanf("%d", &a);
m = b = a;
for(i = ; i < n; i++)
{
scanf("%d", &a);
b = max(a + b, a);
m = max(b,m);
}
printf("%d\n", m);
} return ;
}

在阅读《数据结构与算法 C语言描述》后,发现这个题还有好多解法,撇开时间复杂度是O(n^3)和O(n^2)的算法不谈。

书中也谈到了一个分治算法,没有使用动态规划,时间复杂度是O(NlogN),符合标准的分治递归算法的时间复杂度,原理写成公式一眼明了

f(串)= Max {f(左子串),f(右子串),f(左右串)}

f(左右串)是从中间元素向左右两边扩展的所有子串的最大和

有了上面的规律后不难写出程序,下面的程序没有经过测试,不过原理是正确的

static int maxSubSum(const int a[], int left, int right)
{
if(left == right)
{
if(a[left] > )
return a[left];
else
return ;
} int maxLeft = , maxRight = , maxLeftBorder = , maxRightBorder = ;
int center = (left + right) / ;
maxLeft = maxSubSum(a, left, center);
maxRight = maxSubSum(a, center+, right); for(int i = center; i >= left; --i)
{
int maxLeftBorderTemp = maxLeftBorder + a[i];
if(maxLeftBorderTemp > maxLeftBorder)
maxLeftBorder = maxLeftBorderTemp;
} for(int i = center+; i <= right; ++i)
{
int maxRightBorderTemp = maxRightBorder + a[i];
if(maxRightBorderTemp > maxRightBorder)
maxRightBorder = maxRightBorderTemp;
} int maxBorder = maxLeftBorder + maxRightBorder;
return maxLeft > maxRight ? (maxLeft > maxBorder?maxLeft:maxBorder) : (maxRight>maxBorder?maxRight:maxBorder);
}

还有一个时间复杂度同为O(n)的算法,非常经典,这种算法我自己是肯定想不出来的

书中的号称是最优的算法,叫做联机算法,仅需要常量空间并以线性时间运行。

经过研究这也是利用了动态规划思想。

b[n] = max(a[n] + b[n-], a[n])    when n >
b[0] = a[0]               when n =

同样是这个公式,我们可以改成这种样式

b[n] = max(b[n-], 0) + a[n]     when n >
b[0] = a[0]               when n =

利用这个公式,就可以得出下面的程序

int maxSubSub(const int a[], int N)
{
int b, m, j; b = m = ;
for(j = ; j < N; j++)
{
b += a[j]; if(b > m)
m = b;
else if(b < )
b = ;
}
return m;
}

ACM 子串和的更多相关文章

  1. 【ACM】子串和 - 贪心算法

    子串和 时间限制:5000 ms  |  内存限制:65535 KB 难度:3   描述 给定一整型数列{a1,a2...,an},找出连续非空子串{ax,ax+1,...,ay},使得该子序列的和最 ...

  2. 【ACM】nyoj_132_最长回文子串_201308151713

    最长回文子串 时间限制:1000 ms  |  内存限制:65535 KB 难度:4   描述 输入一个字符串,求出其中最长的回文子串.子串的含义是:在原串连续出现的字符串片段.回文的含义是:正着看和 ...

  3. 牛客练习赛51 B 子串查询 https://ac.nowcoder.com/acm/contest/1083/B

    题目描述 给出一个长度为n的字符串s和q个查询.对于每一个查询,会输入一个字符串t,你需要判断这个字符串t是不是s的子串.子串的定义就是存在任意下标a<b<c<d<e,那么”s ...

  4. ACM进阶计划

    ACM进阶计划ACM队不是为了一场比赛而存在的,为的是队员的整体提高.大学期间,ACM队队员必须要学好的课程有:lC/C++两种语言l高等数学l线性代数l数据结构l离散数学l数据库原理l操作系统原理l ...

  5. 搞ACM的你伤不起[转自RoBa]------(看一次,笑一次)

    RoBa原创,转载请注明出处  劳资六年前开始搞ACM啊!!!!!!!!!! 从此踏上了尼玛不归路啊!!!!!!!!!!!! 谁特么跟劳资讲算法是程序设计的核心啊!!!!!! 尼玛除了面试题就没见过用 ...

  6. 【转】最长回文子串的O(n)的Manacher算法

    Manacher算法 首先:大家都知道什么叫回文串吧,这个算法要解决的就是一个字符串中最长的回文子串有多长.这个算法可以在O(n)的时间复杂度内既线性时间复杂度的情况下,求出以每个字符为中心的最长回文 ...

  7. [转]搞ACM的你伤不起(转自Roba大神)

    劳资六年前开始搞ACM啊!!!!!!!!!! 从此踏上了尼玛不归路啊!!!!!!!!!!!! 谁特么跟劳资讲算法是程序设计的核心啊!!!!!! 尼玛除了面试题就没见过用算法的地方啊!!!!!! 谁再跟 ...

  8. HDU 1503 带回朔路径的最长公共子串

    http://acm.hdu.edu.cn/showproblem.php?pid=1503 这道题又WA了好几次 在裸最长公共子串基础上加了回溯功能,就是给三种状态各做一个 不同的标记.dp[n][ ...

  9. 2013年ACM湖南省赛总结

    今年的比赛最大的变化就是改用OJ判题了,相比于PC^2确实省事了不少,至少可以直接复制样例了.题目方面依旧是刘汝佳命题,这点还是相当好的,至少给人以足够的安全感. 开始比赛之后安叔瞬间就把前半部分题目 ...

随机推荐

  1. delphi popupmenu控件用法

    是,右键菜单控件,和特定的窗体控件的popmenu属性关联就可以了 添加一个popupmenu控件,双击该控件,在弹出的界面中设置好name以及caption属性,点击事件的做法就跟button一样了 ...

  2. Coding 代码管理快速入门

    当项目创建好了之后,我们该如何上传代码到 coding 上呢?Coding 网站使用“ Git 仓库”(类似 github )来管理代码.其操作原理在于:利用 git 服务,将本地的项目目录下的文件同 ...

  3. 如何用C语言封装 C++的类,在 C里面使用

    本文给出了一种方法.基本思想是,写一个 wrapper文件,把 C++类封装起来,对外只提供C语言的接口,和 C++i相关的都在  wrapper的实现文件里实现. 1. apple.h #ifnde ...

  4. MyBatis 的Mapper中有小于号的处理

    <![CDATA[ select * from person t where t.birthday < #{birthday} ]]> 也可以进行转义: < < 小于号 ...

  5. HTTPS=HTTP + SSL / TLS

    以下的两个链接作为本次编辑的参考 https://www.bennythink.com/school-1.htmlhttps://www.bennythink.com/school-2.html 应一 ...

  6. github使用及代码同步

    github是近两年比较火的分布式版本控制工具,很多nb的开源项目代码都托管在github上,比如Facebook.JQuery.Node.js等等,这里简单介绍一下github使用方法以及和本地工程 ...

  7. windows下Visual Studio Code 1.9安装

    点击送你去官网下载vs code 进入下载页面如下 下载完成双击安装 安装完成打开之后如下图,最新版的默认中文就挺好的! 注意下面是微软建议: Note: .NET Framework 4.5.2 i ...

  8. windows下安装redis以及redis扩展,设置redis为windows自启服务

    windows下安装reids windows下redis下载地址:https://github.com/MSOpenTech/redis/releases. 启动redis服务:在redis目录下启 ...

  9. docker - 容器里安装ssh

    docker安装ssh 通过命令行安装 pull ubuntu镜像 docker pull ubuntu:latest 启动并进入bash docker run -it -d ubuntu:laste ...

  10. C# Web.config 配置handlers 和 httpHandlers

    <system.web> <httpHandlers> <add verb="*" path="*.js.axd" type=&q ...