写的第一个版本,使用穷举(暴力)的方法,时间复杂度是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. 关于unity3d播放flash动画,使用插件uniswf

    主要就是代码了. 1.using UnityEngine; using System.Collections; using pumpkin.swf; using System.Collections. ...

  2. android学习日记27--Dialog使用及其设计模式

    1.Dialog概述 对话框一般是一个出现在当前Activity之上的一个小窗口,处于下面的Activity失去焦点, 对话框接受所有的用户交互. 对话框一般用于提示信息和与当前应用程序直接相关的小功 ...

  3. careercup-中等难度 17.6

    17.6 给定一个整数数组,编写一个函数,找出索引m和n,只要将m和n之间的元素排好序,整个数组就是有序的.注意:n越小越好,也就是说,找出符合条件的最短序列. 解法: 开始解题之前,让我们先确认一下 ...

  4. 五、Socket之UDP异步传输文件-实现传输中取消传送

    上一篇文章四.Socket之UDP异步传输文件中,只实现了传输开始前拒绝接收文件,没有实现文件传输进行的时候取消传送,这篇文章中我们就来介绍怎样实现这个功能. 在传输过程中取消文件的传送,有很多地方要 ...

  5. 四、IP地址转换

    IP地址与端口 TCP/IP(传输控制协议/网际协议)不是一个协议,而是一组协议的总称,包括IP.TCP.UDP.ICMP.ARP等.它规范了网络上的所有通信设备,尤其是一个主机与另一个主机之间的数据 ...

  6. C# 之 SqlConnection 类

    一.常用属性 [1]ConnectionString  获取或设置用于打开 SQL Server 数据库的字符串. (重写 DbConnection.ConnectionString.) [2]Con ...

  7. 对springMVC的简单理解

    spring框架以及MVC思想: 一:spring框架:spring框架是一种很优秀的框架,它可以帮助开发人员简化组件与组件之间耦合,管理对象.1:创建对象和管理对象之间的关系,可以在配置文件通过be ...

  8. [转]Oracle Stored Procedures Hello World Examples

    本文转自:http://www.mkyong.com/oracle/oracle-stored-procedures-hello-world-examples/ List of quick examp ...

  9. B/S一些小知识及常用控件

    一: B/S网页的运行 页面在设计的时候,本身就是一个类.在运行的时间,是一个对象. 其中aspx和aspx.cs是在同一个类下. aspx是主要是负责界面,而aspx.cs主要是负责数据逻辑. 呈现 ...

  10. [原创]HTML标签总结!! 第一次画 尚需要改进 多关照

    HTML 页面标签总结  拿xMind写了一下午总结的   只能传图片了   CSS明天整理  后天看看能不能传上来 //======================================= ...