写的第一个版本,使用穷举(暴力)的方法,时间复杂度是O(N^2),执行时间超过限制,代码如下:

 #include <stdio.h>
#define MAX_LEN 100000UL int max_subsequence(int *array, unsigned int len, unsigned int *start, unsigned int *end)
{
int max_val = array[], sum;
int t_start = ; *start = *end = ; while(t_start < len){
sum = ;
for (int i = t_start; i < len; i++){
sum += array[i];
if (sum > max_val){
max_val = sum;
*start = t_start;
*end = i;
}
}
++t_start;
} *start += ;
*end += ;
return max_val;
} int main(void)
{
int A[MAX_LEN];
int i = , round, n, max;
unsigned int start, end; scanf("%d", &round); while (i++ < round)
{
scanf("%d", &n);
for (int j = ; j < n; j++){
scanf("%d", &A[j]);
}
max = max_subsequence(A, n, &start, &end); printf("Case %d:\n", i);
printf("%d %d %d\n\n", max, start, end);
} return ;
}

接着,我又参考了一篇最大子串的文章,编写了下面的代码,成功AC,代码如下:

 #include <stdio.h>
#define MAX_LEN 100000UL int max_subsq(int *array, unsigned int size, unsigned int *start, unsigned int *end)
{
int max_sum = -, sum = ;
int curstart = *start = ;
unsigned int i; for (i = ; i < size; i++){
if (sum < ){
sum = array[i];//丢弃之前的子串
curstart = i; //将当前位置作为新的起始位置
} else {
sum += array[i];
} if (sum > max_sum){
max_sum = sum;
*start = curstart;
*end = i;
}
} return max_sum;
} int main(void)
{
int A[MAX_LEN];
int i = , round, n, max;
unsigned int start, end; scanf("%d", &round); while (i++ < round)
{
scanf("%d", &n);
for (int j = ; j < n; j++){
scanf("%d", &A[j]);
}
max = max_subsq(A, n, &start, &end); printf("Case %d:\n", i);
printf("%d %d %d\n", max, start + , end + ); if (i != round) printf("\n");
} return ;
}

程序的基本思想为:记录前面子序列的和sum,如果和小于0,就丢弃这一段。为什么可以sum<0,就舍弃,重新开始扫描呢?以下证明

我们用i表示子序列的起始下标,j 表示子序列的终止下标。原理是,当我们得到一个子序列,如果子序列的第一个数是非正数,那么可以舍去

当一个子序列的前n个元素和为非正数时,是否也可以舍去呢?答案是可以的。假设k 是i到j中任意一个下标。Sum( a, b ) 表示子序列第a个元素到第b个元素之和。由于加到第j个元素,子序列才开始为负数,所以Sum( i, k ) > 0,Sum( i, k ) + Sum( k, j ) = Sum( i, j ) ,所以Sum( k, j ) < Sum( i, j ) < 0

所以如果把 k到j的序列附加到j之后的序列上,只会使序列越来越小。所以i到j的序列都可以舍去。

但是,要是所有元素都是负数时,此程序能正确定位最大子序列吗?先构造下面的数据:

然后运行程序,结果如下:

因为每次都是先判断sum是否小于0,然后再添加新的元素,最后将sum与max_sum比较。如果全部为负数就变成了每次保留下来的子序列都只有一个元素(array[i]),这样,就相当于在所有负数中寻找最大值。可见,此算法是可行的。

HDOJ(1003) Max Sum的更多相关文章

  1. Hdoj 1003.Max Sum 题解

    Problem Description Given a sequence a[1],a[2],a[3]......a[n], your job is to calculate the max sum ...

  2. 最大子序列和 HDOJ 1003 Max Sum

    题目传送门 题意:求MCS(最大连续子序列和)及两个端点分析:第一种办法:dp[i] = max (dp[i-1] + a[i], a[i]) 可以不开数组,用一个sum表示前i个数字的MCS,其实是 ...

  3. HDOJ 1003 Max Sum(线性dp)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1003 思路分析:该问题为最大连续子段和问题,使用动态规划求解: 1)最优子结构:假设数组为A[0, 1 ...

  4. HDOJ(HDU).1003 Max Sum (DP)

    HDOJ(HDU).1003 Max Sum (DP) 点我挑战题目 算法学习-–动态规划初探 题意分析 给出一段数字序列,求出最大连续子段和.典型的动态规划问题. 用数组a表示存储的数字序列,sum ...

  5. HDU 1003 Max Sum --- 经典DP

    HDU 1003    相关链接   HDU 1231题解 题目大意:给定序列个数n及n个数,求该序列的最大连续子序列的和,要求输出最大连续子序列的和以及子序列的首位位置 解题思路:经典DP,可以定义 ...

  6. hdu 1003 Max Sum (DP)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1003 Max Sum Time Limit: 2000/1000 MS (Java/Others)   ...

  7. hdu 1003 MAX SUM 简单的dp,测试样例之间输出空行

    测试样例之间输出空行,if(t>0) cout<<endl; 这样出最后一组测试样例之外,其它么每组测试样例之后都会输出一个空行. dp[i]表示以a[i]结尾的最大值,则:dp[i ...

  8. HDOJ 3415 Max Sum of Max-K-sub-sequence(单调队列)

    因为是circle sequence,可以在序列最后+序列前n项(或前k项);利用前缀和思想,预处理出前i个数的和为sum[i],则i~j的和就为sum[j]-sum[i-1],对于每个j,取最小的s ...

  9. HDU 1003 Max Sum【动态规划求最大子序列和详解 】

    Max Sum Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Sub ...

随机推荐

  1. Chapter 1 Securing Your Server and Network(11):使用透明数据库加密

    原文出处:http://blog.csdn.net/dba_huangzj/article/details/38398813,专题文件夹:http://blog.csdn.net/dba_huangz ...

  2. navicat for mysql (10038)如何解决,远程无法连接问题

    ubuntu server下安装了MySQL 5.5数据库,然后在windows下通过Navicat for MySQL连接时,出现 Can't connect to mysql server on ...

  3. 眼下最好的JSP分页技术

     2005-08-24   来源:CSDN  作者:wanchao2001 前言     在使用数据库的过程中,不可避免的须要使用到分页的功能,但是JDBC的规范对此却没有非常好的解决.对于这个需求非 ...

  4. iOS快速集成检查更新

    一直以为Appstore有了检查版本是否更新的机制,我们在APP上做这个更新功能会被拒,但是也有看到一些APP也是做了这个更新功能的.因为在网上没有找到完全正确的方法能获取到iTunes里的数据的,于 ...

  5. android的项目文件介绍

    1.res目录存放Android的各种资源文件,比如layout存放布局文件main.xml,values存放各种xml格式的资源文件,字符串资源strings.xml,颜色资源文件:colors.x ...

  6. iOS简单加载一个网页

    .h文件中 @property(strong ,nonitomic) UIWebView * webView; .m文件中 -(void)viewDidLoad { self.webview = [[ ...

  7. PHP读书笔记(2)-变量与数据结构

    php中的数据类型: 一.8种主要数据类型 标量类型 1.整型(int|integer):八进制.十进制.十六进制.超过整型存储范围,会产生溢出. 整型数的字长和平台有关,尽管通常最大值是大约二十亿( ...

  8. iOS-label出现未知边框线的bug

    在前段时间碰到了一个问题  label上出现了一个位置的右边框  仔细查看代码发现没有指定边框 而且奇怪的是只显示右边框  其他边框没有显示 需求效果图: 实际效果图: 结构图: 通过查看结构图  可 ...

  9. mysql命令行方式添加用户及设置权限

    以前总是喜欢通过phpmyadmin去添加用户和数据库,这次装完系统后,配置了一大堆东东,实在不想安装phpmyadmin了,就通过命令行方式创建了数据库和设置权限,记录一下,免得以后总是百度 关键步 ...

  10. 将Oracle表导入到Access方法,已经安装了Access但Win7提示 找不到access driver

    已经安装了Access但Win7提示 找不到access driver: 1.打开 "C:\Windows\SysWOW64\odbcad32.exe" 2.管理员cmd运行 命令 ...