子串和

时间限制: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. 纯代码实现CSS圆角

    我这里说的是纯代码,是指的不使用图片实现圆角,图片实现圆角,这里就不说了. 纯代码实现圆角主要有3种方法: 第一种:CSS3圆角   #chaomao{     border-radius:2px 2 ...

  2. HTML 颜色名

    目前所有浏览器都支持以下颜色名. 141个颜色名称是在HTML和CSS颜色规范定义的(17标准颜色,再加124).下表列出了所有颜色的值,包括十六进制值.  提示: 17标准颜色:黑色,蓝色,水,紫红 ...

  3. NOIP 提高组必会!(转)

    1.排序算法(快排.选择.冒泡.堆排序.二叉排序树.桶排序)2.DFS/BFS 也就是搜索算法,剪枝务必要学! 学宽搜的时候学一下哈希表!3.树 ①遍历 ②二叉树 ③二叉排序树(查找.生成.删除) ④ ...

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

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

  5. PHP中目录解析函数

    dirname(string path):给出一个包含有指向一个文件的全路径的字符串,本函数返回去掉文件名后的目录名. 斜线(/)和反斜线(\)都可以用作目录分隔符.在其它环境下是斜线(/). dir ...

  6. # C#不登录电脑启动程序

    我们知道开机自启动程序如果在用户不登录的情况下是不启动的,但是服务类程序是可以跨过用户登录启动的,例如IIS服务,SQL服务.如果我们已经写好了桌面应用程序,又希望他开机自启动,那就需要借助系统服务在 ...

  7. Kettle(Pentaho)实现web方式远程执行job或transformation

    一.背景 公司在用kettle做数据etl,每做完一个job或transformation发布上线想要立即执行看数据效果的话每次都是找运维同学登陆服务器打开kettle找到对应的文件点击执行,整个过程 ...

  8. Socket通信流程

    Socket通信流程 HTTP 底层就是通过socket建立连接通信管道,实现数据传输 HTTP是一个TCP的传输协议(方式),它是一个可靠,安全的协议

  9. BZOJ-2150部落战争(最小路径覆盖)

    2150: 部落战争 Time Limit: 10 Sec  Memory Limit: 259 MB Description lanzerb的部落在A国的上部,他们不满天寒地冻的环境,于是准备向A国 ...

  10. ubuntu更换内核版本

    一 详细的使用方法见: http://www.xlgps.com/article/310954.html 二 补充: 1 需要删除旧的内核的方法: sudo apt-get remove linux- ...