最大连续子序列和
来源:互联网 发布:软件行业人才需求 编辑:程序博客网 时间:2024/04/24 19:05
1.O(n^2)
基本思路 对所有的情况进行遍历 , 对其实地点i进行遍历 ,为N , 对终止地址j进行遍历 ,为N ,对i到j之间的内容进行累加求和 , 为N 所以能为O(n^3)的解法 ,但是在进行对i到j之间的累加的时候有 sum[i,j]=sum[i,j-1]+a[j]
所以可以压缩到O(n^2)
# include <stdio.h>int n;int a[500];int main(){ while(scanf("%d",&n)!=EOF){ for(int i=0;i<n;i++){ scanf("%d",&a[i]); } int sumi=0,sumj=0; int maxsum = -9999999; for(int i=0;i<n;i++){ int sum=0; for(int j=i;j<n;j++){ sum+=a[j]; if(sum>maxsum){ maxsum = sum; sumi = i; sumj = j; } } } printf("最大的连续子序列为 : %d\n",maxsum); printf("起始位置为 %d 终止为止为 %d\n",sumi+1,sumj+1); } return 0;}2. dp方法 从后向前考虑一下 对于最后一个数 有三种情况 第一个是让他自己成为最大连续子序列 a[n-1] 第二种是 让以a[n-1] 结尾的序列成为最大连续子序列 记为end[n-1] 第三种是a[n-1] 根本就没有包括在最大连续子序列里面 所以就没有他的事 记为all[n-2]
所以在初始化过程中就可以记end[0] = all[0] = a[0]
然后从1开始遍历 得到一个O(n)的解决方案
# include <stdio.h>int n;int a[500];int end[500];int all[500];int max(int a,int b){ return a>b?a:b;}int main(){ while(scanf("%d",&n)!=EOF){ for(int i=0;i<n;i++){ scanf("%d",&a[i]); } all[0] = end[0] =a[0]; for(int i=1;i<n;i++){ end[i]=max(end[i-1]+a[i],a[i]); all[i]=max(all[i-1],end[i]); } printf("%d\n",all[n-1]); } return 0;}
在这之中可以记录一下连续最大子序列的初始位置和最终的位置
也可以有此推出另一种O(n)的方法
# include<stdio.h>int n;int a[500];int main(){ while(scanf("%d",&n)!=EOF){ for(int i=0;i<n;i++){ scanf("%d",&a[i]); } int sum = 0; int maxsum = -99999; int beginsum,endsum; for(int i=0;i<n;i++){ if(sum>=0){ sum+=a[i]; }else{ sum = a[i]; beginsum = i; } if(sum>maxsum){ maxsum = sum; endsum = i; } } printf("%d %d %d\n",maxsum,beginsum,endsum); } return 0;}
3. 如果存在环的话
max(不允许存在环的情况下的最大连续子序列,所有序列的总和减去最小连续子序列的值(转换为对偶问题))
# include<stdio.h>int n;int a[500];int maxsum_limited(){ int sum =0; int maxsum = -999; for(int i=0;i<n;i++){ if(sum<0){ sum = a[i]; }else { sum+=a[i]; } if(sum>maxsum){ maxsum = sum; } } return maxsum;}int maxsum_unlimited(){ int total =0; int sum=0; int minsum =99999; int maxsum_li = maxsum_limited(); if(maxsum_li<0){ return maxsum_li; } for(int i=0;i<n;i++){ if(sum>0){ sum = a[i]; }else{ sum+=a[i]; } if(sum<minsum) minsum = sum; total += a[i]; } return maxsum_li>(total-minsum)?maxsum_li:(total-minsum);}int main(){ while(scanf("%d",&n)!=EOF){ for(int i=0;i<n;i++){ scanf("%d",&a[i]); } int sum = 0; int maxsum = -99999; printf("%d\n",maxsum_unlimited()); } return 0;}
0 0
- 连续子序列最大和
- 最大连续子序列和
- 最大连续子序列和
- 最大连续子序列和
- 最大连续子序列和
- 最大连续子序列和
- 最大连续子序列和
- 最大连续子序列和
- 最大连续子序列和
- 最大连续子序列和
- 最大连续子序列和
- 最大连续子序列和
- 最大连续子序列和
- 最大连续子序列和
- 最大连续子序列和
- 最大连续子序列和
- 最大连续子序列和
- 最大连续子序列和
- ORACLE 10g 升级补丁(Patch)
- 绘制一个普通的蓝色背景的窗口,中间有一个红色的方块
- spring mvc CommonsMultipartResolver文件上传maxUploadSize限制大小
- 开始刷题 leetcode day3: Excel Sheet Column Number
- Android使用SSL
- 最大连续子序列和
- 博客转移
- iOS7隐藏状态栏 status Bar
- XSS Cheat Sheet
- leetcode || 140、Word Break II
- DDoS的攻击原理与防御方法
- enet学习(二):enet_peer_send()函数
- 严重: Exception sending context initialized event to listener instance of class org.springframework.we
- 工业4.0