Max Sum

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 154155    Accepted Submission(s): 35958

Problem Description
Given a sequence a[1],a[2],a[3]......a[n], your job is to calculate the max sum of a sub-sequence. For example, given (6,-1,5,4,-7), the max sum in this sequence is 6 + (-1) + 5 + 4 = 14.
 
Input
The first line of the input contains an integer T(1<=T<=20) which means the number of test cases. Then T lines follow, each line starts with a number N(1<=N<=100000), then N integers followed(all the integers are between -1000 and 1000).
 
Output
For each test case, you should output two lines. The first line is "Case #:", # means the number of the test case. The second line contains three integers, the Max Sum in the sequence, the start position of the sub-sequence, the end position of the sub-sequence. If there are more than one result, output the first one. Output a blank line between two cases.
 
Sample Input
2
5 6 -1 5 4 -7
7 0 6 -1 1 -6 7 -5
 
Sample Output
Case 1:
14 1 4

Case 2:
7 1 6

 
 
 
 

最大连续子序列

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 20109    Accepted Submission(s): 8884

Problem Description
给定K个整数的序列{ N1, N2, ..., NK },其任意连续子序列可表示为{ Ni, Ni+1, ..., 
Nj },其中 1 <= i <= j <= K。最大连续子序列是所有连续子序列中元素和最大的一个, 
例如给定序列{ -2, 11, -4, 13, -5, -2 },其最大连续子序列为{ 11, -4, 13 },最大和 
为20。 
在今年的数据结构考卷中,要求编写程序得到最大和,现在增加一个要求,即还需要输出该 
子序列的第一个和最后一个元素。
 
Input
测试输入包含若干测试用例,每个测试用例占2行,第1行给出正整数K( < 10000 ),第2行给出K个整数,中间用空格分隔。当K为0时,输入结束,该用例不被处理。
 
Output
对每个测试用例,在1行里输出最大和、最大连续子序列的第一个和最后一个元 
素,中间用空格分隔。如果最大连续子序列不唯一,则输出序号i和j最小的那个(如输入样例的第2、3组)。若所有K个元素都是负数,则定义其最大和为0,输出整个序列的首尾元素。 
 
Sample Input
6
-2 11 -4 13 -5 -2
10
-10 1 2 3 4 -5 -23 3 7 -21
6
5 -8 3 2 5 0
1
10
3
-1 -5 -2
3
-1 0 -2
0
 
Sample Output
20 11 13
10 1 4
10 3 5
10 10 10
0 -1 -2
0 0 0

Hint

Hint

Huge input, scanf is recommended.

 
 
 
两题的思路都差不多,假设现在只有s[0]一个元素,现要添加一个元素s[1],那么s[1]要么是新串的起点,要么是原串暂时的终点。如果之前的串的最大和小于0,那么s[1]的值加上原串之后只会小于s[1]本身,所以索性不加,s[1]自己新开一个串,自己作为起点。如果之前的串的最大和大于等于0,那么s[1]就增加到这个串上,并且暂时成为该串的终点。所以每加入一个元素,要么更新起点,要么更新暂时的终点。可以用一个数组DP[i]来保存以[i]为终点的子串的最大值,每次试图更新最大值即可。
 
 
 #include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define MAX 100005 int main(void)
{
int t,n,count;
int dp[MAX];
int max,start,START,end;
count = ; scanf("%d",&t);
while(t --)
{
count ++; scanf("%d",&n);
for(int i = ;i < n;i ++)
scanf("%d",&dp[i]); max = dp[];
start = START = end = ; for(int i = ;i < n;i ++)
{
if(dp[i - ] < && dp[i - ] != dp[i]) //讨论dp[i-1]小于0和大于等于0两种情况即可,后面的条件是为了符合题意
start = i + ; //更新起点
else if(dp[i - ] >= )
dp[i] = dp[i - ] + dp[i]; //隐式地更新终点 if(max < dp[i])
{
START = start;
max = dp[i];
end = i + ;
}
}
printf("Case %d:\n",count);
printf("%d %d %d\n",max,START,end);
if(t)
puts("");
} return ;
}

max sum

上面的代码我用了两个循环,下面这个版本只用了一个,速度反而没第一个快,不知为何。

 #include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define MAX 100005 int main(void)
{
int t,n,count;
int dp[MAX];
int max,start,START,end;
count = ; scanf("%d",&t);
while(t --)
{
count ++; scanf("%d",&n);
for(int i = ;i < n;i ++) //在读入的时候就顺便处理,不知为何会更慢
{
scanf("%d",&dp[i]);
if(!i)
{
max = dp[];
start = START = end = ;
}
else if(dp[i - ] < && dp[i - ] != dp[i])
start = i + ;
else if(dp[i - ] >= )
dp[i] = dp[i - ] + dp[i]; if(max < dp[i])
{
START = start;
max = dp[i];
end = i + ;
}
} printf("Case %d:\n",count);
printf("%d %d %d\n",max,START,end);
if(t)
puts("");
} return ;
}

max sum_2

 #include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define MAX 10005 int main(void)
{
int k;
int dp[MAX],s[MAX],max,max_start,max_end,start; while(scanf("%d",&k) && k)
{
for(int i = ;i < k;i ++)
scanf("%d",&s[i]); max = s[];
dp[] = s[];
max_start = max_end = start = ; for(int i = ;i < k;i ++)
{
if(dp[i - ] < && s[i] != dp[i - ]) //一样的讨论是否为负就行了
{
start = i;
dp[i] = s[i];
}
else if(dp[i - ] >= )
dp[i] = dp[i - ] + s[i]; if(dp[i] > max)
{
max = dp[i];
max_start = start;
max_end = i;
}
} if(max < )
{
max = ;
max_start = ;
max_end = k - ;
}
printf("%d %d %d\n",max,s[max_start],s[max_end]);
} return ;
}

最大连续子序列

这题还有下面这个版本,就是用个双重循环来选出起点和终点,然后就算这个区间的值,可以用一个循环算出以1为起点的值,然后再计算的时候就可以用这个数组推出来,感觉挺不错的,也有DP的思想在里面,虽然超时了。

 #include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define MAX 10005 int main(void)
{
int k,i,j;
long long s[MAX],dp[MAX],box,max,max_i,max_j; while(scanf("%d",&k) && k)
{
scanf("%lld",&dp[]);
s[] = dp[];
for(int i = ;i < k;i ++)
{
scanf("%lld",&dp[i]);
s[i] = dp[i];
dp[i] += dp[i - ]; //DP[i]保存以1为起点i为终点的区间的值
} max = dp[];
max_i = max_j = ;
for(int i = ;i < k;i ++)
for(int j = i;j < k;j ++)
{
if(i)
box = dp[j] - dp[i - ]; //i...j区间的值等于1...j的值减去1...i-1的值
else
box = dp[j]; if(box > max)
{
max = box;
max_i = i;
max_j = j;
}
} if(max < )
{
max = ;
max_i = ;
max_j = k - ;
}
printf("%lld %lld %lld\n",max,s[max_i],s[max_j]);
} return ;
}

最大连续子序列_2

 
 

HDU 1003 Max Sum && HDU 1231 最大连续子序列 (DP)的更多相关文章

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

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

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

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

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

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

  4. HDU 1231.最大连续子序列-dp+位置标记

    最大连续子序列 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Sub ...

  5. hdu 1003 Max Sum (DP)

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

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

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

  7. HDU 1003 Max Sum (动规)

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

  8. hdu 1003 Max sum(简单DP)

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

  9. HDU 1003 Max Sum 解题报告

    题目大意:求一串数字中,几个连续数字加起来最大值,并确定起始和最末的位置. 思路:这是一题DP题,但是可以用尺取法来做.我一开始不会,也是看了某大神的代码,然后有人告诉我这是尺取法,现在会了. //尺 ...

随机推荐

  1. Oracle 分区字段数据更新

    分区字段是不允许进行update操作的,如果有对分区字段行进update,就会报错——ORA-14402:更新分区关键字列将导致分区的更改.  可以通过打开表的row movement属性来允许对分区 ...

  2. Spring REST实践之Spring Web MVC

    Spring概要 Spring Framework提供了依赖注入模型和面向切面编程,简化了基础型代码的编写工作以及更好的能够与其它框架和技术整合起来.Spring Framework由data acc ...

  3. RecyclerView 下拉刷新上拉加载

    步骤: 首先直接定义一个XRecyclerView继承RecyclerView,重写他的三个构造方法. init(Context mContext)方法用来初始化底部加载的view 回到XRecycl ...

  4. C++静态成员函数小结 [转]

    类中的静态成员真是个让人爱恨交加的特性.我决定好好总结一下静态类成员的知识点,以便自己在以后面试中,在此类问题上不在被动. 静态类成员包括静态数据成员和静态函数成员两部分. 一 静态数据成员: 类体中 ...

  5. VPW Communication Protocol

    http://www.fastfieros.com/tech/vpw_communication_protocol.htm Breakdown of the j1850 3 byte Header f ...

  6. TP复习16

    'APP_GROUP_LIST' => 'Home,Admin', //项目分组设定'DEFAULT_GROUP' => 'Home', //默认分组 开分组复制上面 AjaxReturn

  7. [Angular2 Router] Use Params from Angular 2 Routes Inside of Components

    Angular 2’s ActivatedRoute allows you to get the details of the current route into your components. ...

  8. Java Swing 探索(一)LayoutManager

    BorderLayout FlowLayout GridLayout GridBagLayout CardLayout BoxLayout 1.BorderLayout java.lang.Objec ...

  9. android 下修改 hosts文件 及 out of memory的解决

    因为android模拟器host文件无法修改,导致无法通过域名使用http方法调用内网服务,因此从网上大量转载的一种方法,这种方法: 1. 通过emulator -avd avdName -parti ...

  10. 关于javascript中的 执行上下文和对象变量

    什么是执行上下文 当浏览器的解释器开始执行我们的js代码的时候,js代码运行所处的环境可以被认为是代码的执行上下文,执行上下文(简称-EC)是ECMA-262标准里的一个抽象概念,用于同可执行代码(e ...