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]为终点的子串的最大值,每次试图更新最大值即可。
 
 
  1. #include<stdio.h>
  2. #include<stdlib.h>
  3. #include<string.h>
  4. #define MAX 100005
  5.  
  6. int main(void)
  7. {
  8. int t,n,count;
  9. int dp[MAX];
  10. int max,start,START,end;
  11. count = ;
  12.  
  13. scanf("%d",&t);
  14. while(t --)
  15. {
  16. count ++;
  17.  
  18. scanf("%d",&n);
  19. for(int i = ;i < n;i ++)
  20. scanf("%d",&dp[i]);
  21.  
  22. max = dp[];
  23. start = START = end = ;
  24.  
  25. for(int i = ;i < n;i ++)
  26. {
  27. if(dp[i - ] < && dp[i - ] != dp[i]) //讨论dp[i-1]小于0和大于等于0两种情况即可,后面的条件是为了符合题意
  28. start = i + ; //更新起点
  29. else if(dp[i - ] >= )
  30. dp[i] = dp[i - ] + dp[i]; //隐式地更新终点
  31.  
  32. if(max < dp[i])
  33. {
  34. START = start;
  35. max = dp[i];
  36. end = i + ;
  37. }
  38. }
  39. printf("Case %d:\n",count);
  40. printf("%d %d %d\n",max,START,end);
  41. if(t)
  42. puts("");
  43. }
  44.  
  45. return ;
  46. }

max sum

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

  1. #include<stdio.h>
  2. #include<stdlib.h>
  3. #include<string.h>
  4. #define MAX 100005
  5.  
  6. int main(void)
  7. {
  8. int t,n,count;
  9. int dp[MAX];
  10. int max,start,START,end;
  11. count = ;
  12.  
  13. scanf("%d",&t);
  14. while(t --)
  15. {
  16. count ++;
  17.  
  18. scanf("%d",&n);
  19. for(int i = ;i < n;i ++) //在读入的时候就顺便处理,不知为何会更慢
  20. {
  21. scanf("%d",&dp[i]);
  22. if(!i)
  23. {
  24. max = dp[];
  25. start = START = end = ;
  26. }
  27. else if(dp[i - ] < && dp[i - ] != dp[i])
  28. start = i + ;
  29. else if(dp[i - ] >= )
  30. dp[i] = dp[i - ] + dp[i];
  31.  
  32. if(max < dp[i])
  33. {
  34. START = start;
  35. max = dp[i];
  36. end = i + ;
  37. }
  38. }
  39.  
  40. printf("Case %d:\n",count);
  41. printf("%d %d %d\n",max,START,end);
  42. if(t)
  43. puts("");
  44. }
  45.  
  46. return ;
  47. }

max sum_2

  1. #include<stdio.h>
  2. #include<stdlib.h>
  3. #include<string.h>
  4. #define MAX 10005
  5.  
  6. int main(void)
  7. {
  8. int k;
  9. int dp[MAX],s[MAX],max,max_start,max_end,start;
  10.  
  11. while(scanf("%d",&k) && k)
  12. {
  13. for(int i = ;i < k;i ++)
  14. scanf("%d",&s[i]);
  15.  
  16. max = s[];
  17. dp[] = s[];
  18. max_start = max_end = start = ;
  19.  
  20. for(int i = ;i < k;i ++)
  21. {
  22. if(dp[i - ] < && s[i] != dp[i - ]) //一样的讨论是否为负就行了
  23. {
  24. start = i;
  25. dp[i] = s[i];
  26. }
  27. else if(dp[i - ] >= )
  28. dp[i] = dp[i - ] + s[i];
  29.  
  30. if(dp[i] > max)
  31. {
  32. max = dp[i];
  33. max_start = start;
  34. max_end = i;
  35. }
  36. }
  37.  
  38. if(max < )
  39. {
  40. max = ;
  41. max_start = ;
  42. max_end = k - ;
  43. }
  44. printf("%d %d %d\n",max,s[max_start],s[max_end]);
  45. }
  46.  
  47. return ;
  48. }

最大连续子序列

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

  1. #include<stdio.h>
  2. #include<stdlib.h>
  3. #include<string.h>
  4. #define MAX 10005
  5.  
  6. int main(void)
  7. {
  8. int k,i,j;
  9. long long s[MAX],dp[MAX],box,max,max_i,max_j;
  10.  
  11. while(scanf("%d",&k) && k)
  12. {
  13. scanf("%lld",&dp[]);
  14. s[] = dp[];
  15. for(int i = ;i < k;i ++)
  16. {
  17. scanf("%lld",&dp[i]);
  18. s[i] = dp[i];
  19. dp[i] += dp[i - ]; //DP[i]保存以1为起点i为终点的区间的值
  20. }
  21.  
  22. max = dp[];
  23. max_i = max_j = ;
  24. for(int i = ;i < k;i ++)
  25. for(int j = i;j < k;j ++)
  26. {
  27. if(i)
  28. box = dp[j] - dp[i - ]; //i...j区间的值等于1...j的值减去1...i-1的值
  29. else
  30. box = dp[j];
  31.  
  32. if(box > max)
  33. {
  34. max = box;
  35. max_i = i;
  36. max_j = j;
  37. }
  38. }
  39.  
  40. if(max < )
  41. {
  42. max = ;
  43. max_i = ;
  44. max_j = k - ;
  45. }
  46. printf("%lld %lld %lld\n",max,s[max_i],s[max_j]);
  47. }
  48.  
  49. return ;
  50. }

最大连续子序列_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. PetaPoco T4模板修改生成实体

    PetaPoco T4 模板生成的实体类全部包含再一个.CS文件中.通过修改PetaPoco的T4模板,生成单文件实体. 1.生成单CS文件模板: SigleFile.ttinclude <#@ ...

  2. MRI中T1和T2的含义与区分[转]

    A. MRI名词解释   T1加权像.T2加权像为磁共振检查中报告中常提到的术语,很多非专业人士不明白是什么意思,要想认识何为T1加权像.T2加权像,请先了解几个基本概念:   1.磁共振(maget ...

  3. GetSafeHwnd()函数解释[转]

    当我们想得到一个窗口对象(CWnd的派生对象)指针的句柄(HWND)时,最安全的方法是使用GetSafeHwnd()函数,通过下面的例子来看其理由: CWnd *pwnd = FindWindow(“ ...

  4. DOM-判断元素节点类型

    http://stackoverflow.com/questions/384286/javascript-isdom-how-do-you-check-if-a-javascript-object-i ...

  5. TL-WR703 USB不稳定/当前的总结

    http://see.sl088.com/wiki/WR703_USB%E4%B8%8D%E7%A8%B3%E5%AE%9A/%E5%BD%93%E5%89%8D%E7%9A%84%E6%80%BB% ...

  6. Gmail POP3设置

    好几个同事在问我怎样使用ThunderBird和OE收取IT CHT的邮箱,因为IT CHT就是用Gmail的功能,因此收发邮件是跟Gmail一样,下面是Gmail的POP&SMTP的设置方法 ...

  7. EntityFramework Code First 优化-IIS 8的第一次优化请求配置

    首先需要在Window中添加Application Initialization Application Initialization 在IIS中配置Application Pool 编辑Applic ...

  8. cocos2dx A*算法

    头文件和源文件拷贝到项目中就能用了! have fun 使用cocos2dx 3.2 原理都一样 淡蓝色的点是地图 深蓝色的点是障碍物 绿色的点是路径 暗绿色的点是搜寻过的点 红色的点是按路径行走的点 ...

  9. JS可以做什么,它的能力范围 View----------Request/Submit------------------Server

    View----------Request/Submit------------------Server javascript--------><script>标签方式(页面,动态插 ...

  10. 去掉或者修改 input、select 等表单的【默认样式 】

    隐藏input等表单的默认样式的背景: textarea,select,input{-webkit-appearance: none; -moz-appearance: none; -o-appear ...