杭电1003--连续最长子序列
2015-11-08 22:56
351 查看
Max Sum
Problem Description
Given a sequence a[1],a[2],a[3]……a
, 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
解法1:
# include <iostream> # include <cstdio> int main(){ int n,m; int i,j,k=0; scanf("%d",&n); while(n--){ scanf("%d",&m); int sum = 0,max=-99999; int t,sta=0,en=0,sta_t=0; for(i=0;i<m;i++){ scanf("%d",&t); sum+=t; if(sum>max){//增长 max = sum; en = i; sta = sta_t;//sum<0起的作用 } if(sum<0){//保存下一个可能存在最大值的起始位置 sum = 0; sta_t=i+1; } } printf("Case %d:\n",++k); printf("%d %d %d\n",max,sta+1,en+1); if(n!=0)printf("\n"); } return 0; }
解法2:
# include <iostream> # include <cstdio> struct pos{ int r; int l; }; pos p[1000000]; int s[1000000]; int main(){ int T; int n; scanf("%d",&T); for(int i=1;i<=T;i++){ scanf("%d",&n); for(int j=1;j<=n;j++){ scanf("%d",&s[j]); } p[1].l = 1; p[1].r = 1; for(int k=2;k<=n;k++){ if(s[k-1]+s[k]>s[k]){//说明增长 s[k] = s[k-1]+s[k]; p[k].l = p[k-1].l; p[k].r = k; }else{ s[k] = s[k]; p[k].l=p[k].r=k; } } int maxR = s[1]; int maxId = 1; for(int j=2;j<=n;j++){ if(s[j]>maxR){ maxR = s[j]; maxId = j; } } if(i!=1) printf("\n"); printf("Case %d:\n",i); printf("%d %d %d\n",maxR,p[maxId].l,p[maxId].r); } return 0; }
方法3:
转载:/article/2447402.html
#include<iostream> #include<vector> using namespace std; int main() { int T,n,i,start,end,k; cin>>T; for(int j=1;j<=T;j++)//因为下面需要输出数字串的起始与结束位置,其与i有关故在此将i设计为从1开始 { cin>>n; vector<int>arr(n+1,0); // 这个是表示建立一个容器,里面有n+1个变量,每个变量初始化为0他的作用类似于数组 int sum=0; start=end=k=1; int maxn=-1001 ; for(i=1;i<=n;i++) { cin>>arr[i]; sum+=arr[i]; if(maxn<sum)//这一句就是为了找出在数字串的最大值。sum是记录数字串相加的大小,如果有大的就交换值 { maxn=sum; end=i; // 只要是数字串的只在增大就表示着个数字是可以加上去的;所以结束的得地方是和i是同步的 start=k;//设计的时候始终记住就是这两个数是同是在成功的时候可以变得,但是开始的数字就是在不成功的时候也是会变化的, 所以我们要记住在这种情况下,就是要定格 } if(sum<0) { sum=0 ; // 当sum的结果是负数时,我们就把下一个数组的值交给sum,比如2,-3,这时sum=-1,我们就不要这个结果了, // 因为他已经不可能是最大值了,就令sum=0;相加是在上面事实现的。 k=i+1; // 这个时候初始的地方也是要变得如上面的2,-3,原来是start=1,这时直接转到3上因为i=2了。 } } cout<<"Case "<<j<<":\n"<<maxn<<" "<<start<<" "<<end<<endl; if(j!=T)cout<<endl; } return 0; } 下面贴几个例子,如果这几个例子过了就差不多了 -1 -2 -3 10(在此省略了前面的数字,下同) 结果:Case 1: 10 4 4 1 2 3 -100 1 2 3 -100 1 2 2 2 2 结果Case 2:9 9 13 -1 -2 -3 -4 -5 结果:Case 3:-1 1 1 -3 -2 -1 -2 -3 结果:Case 4:-1 3 3 0 0 2 0 结果:Case :2 1 3
方法4:
#include<stdio.h> int main() { int i,ca=1,t,s,e,n,x,now,before,max; scanf("%d",&t); while(t--) { scanf("%d",&n); for(i=1;i<=n;i++) { scanf("%d",&now); if(i==1)//初始化 { max=before=now;//max保留之前算出来的最大和,before存储目前在读入数据前保留的和,now保留读入数据 x=s=e=1;//x用来暂时存储before保留的和的起始位置,当before>max时将赋在s位置,s,e保留最大和的start和end位置 } else { if(now>now+before)//如果之前存储的和加上现在的数据比现在的数据小,就把存储的和换成现在的数据,反之就说明数据在递增,可以直接加上 { before=now; x=i;//预存的位置要重置 } else before+=now; } if(before>max)//跟之前算出来的最大和进行比较,如果大于,位置和数据就要重置 max=before,s=x,e=i; } printf("Case %d:n%d %d %dn",ca++,max,s,e); if(t)printf("n"); } return 0; }
方法5:
# include <iostream> # include <cstdio> using namespace std; int dp[100009],a[100009]; int main(){ int T,n,m; int i,j,k; int cnt = 0; scanf("%d",&T); while(T--){ scanf("%d",&n); for(int i=0;i<n;i++) scanf("%d",&a[i]); dp[0]=a[0];//dp记录第一个位置 int start=0,end=0;///记录当前最大的dp int l=0,r=0;//更新每次的下标 int max_s = a[0];//记录最大的dp for(j=1;j<n;j++){ if(dp[j-1]>=0){ dp[j] = dp[j-1] + a[j];r=j;//这里可能存在最大的dp,所以需要记录dp的下标 }else{ //走到这里,说明dp[j-1]<0 dp[j] = a[j];l=r=j;//需要记录新的位置 } if(max_s<=dp[j]){//如果当前的dp取得最大值,需要记录 max_s = dp[j]; start = l; end = r; } } printf("Case %d:\n",++cnt); printf("%d %d %d\n",max_s,start+1,end+1); if(T) printf("\n"); } return 0; }
相关文章推荐
- Nov 8th
- POJ - 2019 Cornfields(二维RMQ)
- JAVA 中URL中文参数乱码的处理方法(汇总)
- JSP自定义标签(转)
- python之模块copy,了解概念即可
- 【算法】多种排序
- ThinkPHP中foreach和volist的区别
- 通过Demo了解AlertDialog的构造原理
- Hadoop数据类型讲解
- 典型用户
- jvm垃圾回收方式和性能调优
- Linux学习之命令(用户、压缩)
- Linux下非轮询方式监控网卡连接状态
- Spark standalone集群安装
- DB之MyEclipse连接MySQL
- 构造函数
- LintCode-有效回文串
- 宏定义中的选择判断句
- Linux下如何清空输入缓冲区
- memcpy函数的使用