子串和

时间限制: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. SecureCRT 使用

    1. 连接linux 服务器 http://www.cnblogs.com/SimonGao/p/4959274.html

  2. WPF中将16进制颜色码转换成SolidColorBrush

    使用ColorConverter.ConvertFromString(string colorValue)方法 例如:new SolidColorBrush((Color)ColorConverter ...

  3. 阿里云服务器windows系统C盘一键清理脚本

    @ECHO OFF @echo @echo @echo 清理几个比较多垃圾文件的地方 DEL /F /S /Q "C:\WINDOWS\PCHealth\ERRORREP\QSIGNOFF\ ...

  4. Markdown使用教程

    Markdown 是一种 轻量级标记语言,主要特点是:使用易读易写的纯文本格式编写文档,然后转换成有效的XHTML(或者HTML)文档". 本文参考了:语法手册.简书介绍. 常用语法 一.标 ...

  5. POJ2796(单调栈)

    Feel Good Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 12987   Accepted: 3639 Case T ...

  6. 在ubuntu linux 中编写一个自己的bash脚本

    在ubuntu linux 中编写一个自己的简单的bash脚本. 实现功能:终端中输入简单的命令(以pm为例(play music)),来实现音乐的播放.注:本人ununut中安装了audacious ...

  7. display的none与block(判断登录界面的账号密码是否为空)

    判断登录界面的账号密码是否为空的时候又不想用alert显示就需要用display来隐藏alert啦(在设置时切忌要将隐藏的内容写在账号和密码的div中,否则会根据屏幕的分辨率不同而有所变化,这是本人教 ...

  8. cordova调用本地SQLite数据库的方法

    第一篇技术博客,写下来和大家分享今天所学,其次自己也巩固一下. 整个下午的时间用来钻研如何用cordova调用移动端本地SQLite数据库.首先我并不是用eclipse来编程的,而是用cordova建 ...

  9. python中的select模块

    介绍: Python中的select模块专注于I/O多路复用,提供了select  poll  epoll三个方法(其中后两个在Linux中可用,windows仅支持select),另外也提供了kqu ...

  10. 【闲聊PHP】编程界的萝莉小美女--PHP

    本文地址 01 前言--上了贼船 不知道何时就上了PHP的贼船了,开始了web的开发,记得差不多两年前我还是做传统电子行业的人,就是嵌入式的方向,那时在天津或摆弄手机,或下煤窑摆弄电话,抑或就是在医疗 ...