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. WPF的DataGrid绑定ItemsSource后第一次加载数据有个别列移位的解决办法

    最近用WPF的DataGrid的时候,发现一个很弱智的问题,DataGrid的ItemsSource是绑定了一个属性: 然后取数给这个集合赋值的时候,第一次赋值,就会出现列移位 起初还以为是显卡的问题 ...

  2. (剑指Offer)面试题32:从1到n整数中1出现的次数

    题目: 输入一个整数n,求从1到n这n个整数的十进制表示中1出现的次数.例如输入12,从1到12这些整数中包含1的数字有1,10,11和12,一共出现了5次. 思路: 1.累加法 累加1到n中每个整数 ...

  3. WSO2 Stratos手册

    WSO2 Stratos是最完整的企业级cloud solution,提供了一个开放的PaaS平台,相比于其他的PaaS平台来说,Stratos支持更多核心的服务.Stratos2.0对那些想从异构环 ...

  4. Linux 上的基础网络设备详解

    抽象网络设备的原理及使用 网络虚拟化是 Cloud 中的一个重要部分.作为基础知识,本文详细讲述 Linux 抽象出来的各种网络设备的原理.用法.数据流向.您通过此文,能够知道如何使用 Linux 的 ...

  5. codis3.1集群搭建

    Codis31搭建 codis 3.1 安装搭建 一.基本信息 1. 服务器基本信息 ip地址 安装服务 172.16.200.71 zk1.codis-dashboard.codis-fe.codi ...

  6. android自定义相册 支持低端机不内存溢出

    1 之前在网上看的自定义相册很多时候在低端机都会内存溢出开始上代码把 首先我们要拿到图片的所有路径 cursor = context.getContentResolver().query( Media ...

  7. nodejs以及npm的安装

    参考资料:http://xiaoyaojones.blog.163.com/blog/static/28370125201351501113581/ 上面的仁兄说的比较清楚,基本解决了安装中遇到的问题 ...

  8. linux系统命令解析(0基础篇)

    经常使用命令 ctrl+W+T    当进入gvim文档编辑界面后,假设是C文件,能够列出当前文件里的全部函数. Shift+*    当进入gvim文档编辑页面,能够搜索当前keyword. ech ...

  9. 怎样对ListView的项进行排序

    当您使用资源浏览器查看文件时,您能够随心所欲的按名称.大小.类型及改动日期不同的列对文件进行大小排序..Net提供的ListView组件没有直接提供这样的功能,但要实现并不难.   ListView. ...

  10. CentOS 6.4安装本地yum源,并安装X Window System

    1.为DVD创建一个挂载目录 [root@localhost ~]# mkdir /media/CentOS 2.在Linux下挂载CentOS DVD(虚拟机挂载DVD不说了,应该都会) [root ...