Codeup-问题 A: 最大连续子序列
题目描述
给定K个整数的序列{ N1, N2, ..., NK },其任意连续子序列可表示为{ Ni, Ni+1, ..., Nj },其中 1 <= i <= j <= K。最大连续子序列是所有连续子序列中元素和最大的一个,例如给定序列{ -2, 11, -4, 13, -5, -2 },其最大连续子序列为{ 11, -4, 13 },最大和为20。现在增加一个要求,即还需要输出该子序列的第一个和最后一个元素。
输入
测试输入包含若干测试用例,每个测试用例占2行,第1行给出正整数K( K<= 10000 ),第2行给出K个整数,中间用空格分隔,每个数的绝对值不超过100。当K为0时,输入结束,该用例不被处理。
输出
对每个测试用例,在1行里输出最大和、最大连续子序列的第一个和最后一个元素,中间用空格分隔。如果最大连续子序列不唯一,则输出序号i和j最小的那个(如输入样例的第2、3组)。若所有K个元素都是负数,则定义其最大和为0,输出整个序列的首尾元素。
样例输入
5
-3 9 -2 5 -4
3
-2 -3 -1
0
样例输出
12 9 5
0 -2 -1
提示
这是一道稍微有点难度的动态规划题。
首先可以想到的做法是枚举每个区间的和,预处理sum[i]来表示区间[1, i]的和之后通过减法我们可以O(1)时间获得区间[i, j]的和,因此这个做法的时间复杂度为O(n^2)。
然后这题的数据范围较大,因此还需作进一步优化才可以AC。记第i个元素为a[i],定义dp[i]表示以下标i结尾的区间的最大和,那么dp[i]的计算有2种选择,一种是含有a[i-1],一种是不含有a[i-1],前者的最大值为dp[i-1]+a[i],后者的最大值为a[i]。而两者取舍的区别在于dp[i-1]是否大于0。
WA原因:答案错误50%,暂时还没有排查出原因
#include <iostream>
#include <algorithm>
#include <vector>using namespace std;
const int maxn = 10000;
int A[maxn], dp[maxn];
//vector<int> p[maxn]; //记录序列,pi表示以i结尾的序列
int k;
int mx;
int minusNum;
int ans = 0;int main()
{while(scanf("%d", &k) && k){fill(dp,dp+k,0);
// for(int i = 0; i < k; i++)
// {
// p[i].clear();
// }minusNum = 0;for(int i = 0; i < k; i++){scanf("%d", &A[i]);if(A[i] < 0) minusNum++;}//所有k个元素都为负if(minusNum == k) printf("0 %d %d\n", A[0], A[k-1]);else{dp[0] = 0;
// p[0].push_back(0);for(int i = 1; i < k; i++){if(dp[i-1] < 0) //只有A[i]一个元素{dp[i] = A[i];
// p[i].push_back(i);}else{
// p[i] = p[i-1];
// p[i].push_back(i);dp[i] = dp[i-1] + A[i];}}mx = 0;int ans1 = 0, ans2 = 0;int b1, b2;for(int i = 0; i < k; i++){if(dp[i] > dp[mx]){mx = i;}else if(dp[i] == dp[mx]){
// int ans1 = p[i][0] + p[i][p[i].size() - 1];
// int ans2 = p[mx][0] + p[mx][p[mx].size() - 1];
// if(ans1 > ans2) mx = i;if(dp[i] == A[i]){ans1 = A[i];}else{b1 = i;while(dp[b1] != 0){dp[b1--] -= A[b1];}ans1 = A[b1+1] + A[i];}if(dp[mx] == A[i]){ans2 = A[mx];}else{b2 = mx;while(dp[b2] != 0){dp[b2--] -= A[b2];}ans2 = A[b2+1] + A[mx];}if(ans1 < ans2) mx = i;}}printf("%d ", dp[mx]);if(dp[mx] == A[mx]){printf("%d\n", A[mx]);}else{ans = A[mx];while(dp[mx] != 0){dp[mx--] -= A[mx];}printf("%d %d\n", A[mx+1], ans);}}}return 0;}
Codeup-问题 A: 最大连续子序列相关推荐
- HDU 1231 最大连续子序列
最大连续子序列 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Su ...
- 最大连续子序列(dp)
Problem Description 给定K个整数的序列{ N1, N2, ..., NK },其任意连续子序列可表示为{ Ni, Ni+1, ..., Nj },其中 1 <= i < ...
- 最大连续子序列和-动态规划
题目描述: 给定K个整数的序列{ N1, N2, -, NK },其任意连续子序列可表示为{ Ni, Ni+1, -, Nj },其中 1 <= i <= j <= K.最大连续子序 ...
- [数字技巧]最大连续子序列和
最大连续子序列和这个问题是一个比较常见的问题,出现在很多公司的面试笔试中.题目大概是这样描述的: 输入一个整形数组,数组中有正数也有负数,数组中连续一个或多个组成一个子序列,每个子序列都有一个和,求所 ...
- 最大连续子序列乘积(DP)
题目来源:小米手机2013年校园招聘笔试题题目描述: 给定一个浮点数序列(可能有正数.0和负数),求出一个最大的连续子序列乘积. 输入: 输入可能包含多个测试样例. 每个测试样例的第一行仅包含正整数 ...
- 四种方法解决最大连续子序列和问题
四种方法解决最大连续子序列和问题 参考文章: (1)四种方法解决最大连续子序列和问题 (2)https://www.cnblogs.com/AlvinZH/p/6795647.html 备忘一下.
- 九度OJ 1011:最大连续子序列 (DP)
时间限制:1 秒 内存限制:32 兆 特殊判题:否 提交:5615 解决:2668 题目描述: 给定K个整数的序列{ N1, N2, ..., NK },其任意连续子序列可表示为{ Ni, Ni+1, ...
- 最小正连续子序列和 问题
2019独角兽企业重金招聘Python工程师标准>>> 给你一个数组a[1...n],求最小正连续子序列和 这个问题不能用dp解,因为不具有最优子结构.只能尝试其他方法. 常用定义, ...
- HDU 1231 最大连续子序列:水dp
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1231 题意: 给你一个整数序列,求连续子序列元素之和最大,并输出该序列的首尾元素(若不唯一,输出首坐标 ...
- 《github一天一道算法题》:分治法求数组最大连续子序列和
看书.思考.写代码. /**************************************** copyright@hustyangju * blog: http://blog.csdn.n ...
最新文章
- 10本计算机视觉必读经典图书,入门篇 + 提升篇
- Linux下克隆的修改IP
- vb.net datagridview数据批量导入sql_导入:Java实现大批量数据导入导出(100W以上)
- 如何对memcache的数据(key-value)进行遍历操作
- Oracle中给表添加主键 外键,给表中添加主键、外键
- 对C#中事件的简单理解
- 【TWVRP】基于matlab遗传算法求解带时间窗的外卖配送车辆路径规划问题【含Matlab源码 1416期】
- 【总结】编程语言的分类
- php考勤管理系统论文,基于PHP的高职院校学生考勤管理系统的研究
- java实现阿里云图片文字识别
- 解决Vmware虚拟机startx进入图形界面卡退、白屏、黑屏的问题
- JAVA面试八股文宝典(黑马学习随笔)-- 基础篇
- (排序5)快速排序(Hoare,选key的随机数与三数取中优化,挖坑法与前后指针法等)
- PPT2010封装为exe教程
- 如何通adb命令删除安卓设备上指定的文件和apk
- 作为一个研发背景出身的项目经理写给IT面试者的几点建议
- Windows App开发之更多技巧
- 一款实用的屏幕绘制标注和鼠标高亮工具:Presentify Mac
- 判断素数三种方法(转自阿飞__)
- 【配电网规划】配电网网架重构、DG位置选择容量配置(Matlab代码实现)