写的第一个版本,使用穷举(暴力)的方法,时间复杂度是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. discuz!版本号信息改动步骤

    建完网站后,就到了改动discuz! 论坛的步骤了,,将其改动为自己喜欢的样子.是非常有意思的,废话不多说了.以下给大家介绍改动的方法. 1.[改动后台-首页的版权]打开ftp.连接网站,进入到:/f ...

  2. Access-数据类型与.net OleDbType枚举类型对应关系

    列表最常见的数据类型映射 访问类型名称 数据库数据类型 OLEDB 类型 .NET 框架类型 成员名称 文本 VarWChar DBTYPE _ WSTR System.String OleDbTyp ...

  3. 微信公众平台java开发详解(工程代码+解析)

    原文:http://blog.csdn.net/pamchen/article/details/38718947 说明:本次的教程主要是对微信公众平台开发者模式的讲解,网络上很多类似文章,但很多都让初 ...

  4. [Node.js] Using npm link to use node modules that are "in progress"

    It is some times convenient, even necessary, to make use of a module that you are working on before ...

  5. iOS快速集成检查更新

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

  6. Advanced Configuration Tricks

    Advanced Configuration Tricks Configuration of zend-mvc applications happens in several steps: Initi ...

  7. 面试体验:Google 篇(转)

    http://www.cnblogs.com/cathsfz/archive/2012/08/08/google-interview-experience.html 尝试在自己的博客上搜索点东西,结果 ...

  8. 《Mysql 公司职员学习篇》 第二章 小A的惊喜

          第二章 小A的惊喜  ---- 认识数据库 吃完饭后,小Y和小A回到了家里,并打开电脑开始学习Mysql. 小Y:"小A,你平时的Excell文件很多的情况下,怎么样存放Exce ...

  9. angularjs Failed to read the 'selectionStart' property from 'HTMLInputElement':

    在找angularjs input(type='number')在获取焦点的时候,文本框内容选中效果,参考了:Select text on input focus,我直接复制他的code之后,在ion ...

  10. [记录] js判断数组key是否存在

    数组中判断key是否存在 可以通过arrayObject.hasOwnProperty(key)来进行判断数组key是否存在,返回的是boolean值,如果存在就返回true,不存在就返回false ...