HDU 1003 Max Sum && HDU 1231 最大连续子序列 (DP)
Max Sum
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 154155 Accepted Submission(s): 35958
5 6 -1 5 4 -7
7 0 6 -1 1 -6 7 -5
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
Nj },其中 1 <= i <= j <= K。最大连续子序列是所有连续子序列中元素和最大的一个,
例如给定序列{ -2, 11, -4, 13, -5, -2 },其最大连续子序列为{ 11, -4, 13 },最大和
为20。
在今年的数据结构考卷中,要求编写程序得到最大和,现在增加一个要求,即还需要输出该
子序列的第一个和最后一个元素。
素,中间用空格分隔。如果最大连续子序列不唯一,则输出序号i和j最小的那个(如输入样例的第2、3组)。若所有K个元素都是负数,则定义其最大和为0,输出整个序列的首尾元素。
-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
10 1 4
10 3 5
10 10 10
0 -1 -2
0 0 0
Hint
Huge input, scanf is recommended.
#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)的更多相关文章
- HDU 1003 Max Sum【动态规划求最大子序列和详解 】
Max Sum Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Sub ...
- HDU 1003 Max Sum --- 经典DP
HDU 1003 相关链接 HDU 1231题解 题目大意:给定序列个数n及n个数,求该序列的最大连续子序列的和,要求输出最大连续子序列的和以及子序列的首位位置 解题思路:经典DP,可以定义 ...
- HDOJ(HDU).1003 Max Sum (DP)
HDOJ(HDU).1003 Max Sum (DP) 点我挑战题目 算法学习-–动态规划初探 题意分析 给出一段数字序列,求出最大连续子段和.典型的动态规划问题. 用数组a表示存储的数字序列,sum ...
- HDU 1231.最大连续子序列-dp+位置标记
最大连续子序列 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Sub ...
- hdu 1003 Max Sum (DP)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1003 Max Sum Time Limit: 2000/1000 MS (Java/Others) ...
- hdu 1003 MAX SUM 简单的dp,测试样例之间输出空行
测试样例之间输出空行,if(t>0) cout<<endl; 这样出最后一组测试样例之外,其它么每组测试样例之后都会输出一个空行. dp[i]表示以a[i]结尾的最大值,则:dp[i ...
- HDU 1003 Max Sum (动规)
Max Sum Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Su ...
- hdu 1003 Max sum(简单DP)
Max Sum Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Problem ...
- HDU 1003 Max Sum 解题报告
题目大意:求一串数字中,几个连续数字加起来最大值,并确定起始和最末的位置. 思路:这是一题DP题,但是可以用尺取法来做.我一开始不会,也是看了某大神的代码,然后有人告诉我这是尺取法,现在会了. //尺 ...
随机推荐
- android AChartEngine图标引擎
AChartEngine 1.在androi开发中的时候很多时候是要用图表将数据直观的显示出来的,这里就要用到AChartEngine. XMultipleSeriesRenderer 是经常要用到的 ...
- Java的初步认识
PS:弥补那些错过的时间,弥补那些本是决定做而没有做的事情,当初说好了学习编程要把自己学到的或是理解的写到博客中记录下来,可是由于各种缘由最终是没有实现...经过几番周折决定把那些丢掉的重新捡起来.对 ...
- 设置文字在div中垂直居中,使用line-height
(从已经死了一次又一次终于挂掉的百度空间人工抢救出来的,发表日期2014-02-19) line-height 行间距 详细使用方法:http://www.w3school.com.cn/css/pr ...
- .git文件过大!删除大文件
在我们日常使用Git的时候,一般比较小的项目,我们可能不会注意到.git 这个文件. 其实, .git文件主要用来记录每次提交的变动,当我们的项目越来越大的时候,我们发现 .git文件越来越大. 很大 ...
- jQuery日历和日期选取插件
参考网站:http://developer.51cto.com/art/201103/248670.htm http://www.open-open.com/ajax/3_Calendar.htm 推 ...
- IIS启用.net2.0
如果先安装.net2.0,后安装iis,则在IIS服务扩展中无法看到.net2.0,按如下方法可启用: C:/WINDOWS/Microsoft.NET/Framework/v2.0.50727/as ...
- Android Volley框架的使用(三)
此博文源码下载地址 https://github.com/Javen205/VolleyDemo.git Image Request 为了更方便的使用Volley中的图片请求,我们同样先在Voll ...
- 容器的end()方法
容器的end()方法,返回一个迭代器,需要注意:这个迭代器不指向实际的元素,而是表示末端元素的下一个元素,这个迭代器起一个哨兵的作用,表示已经处理完所有的元素. 因此,在查找的时候,返回的迭代器,不等 ...
- 一个jQuery扩展工具包
带有详尽注释的源代码: var jQuery = jQuery || {}; // TODO // ###################################string操作相关函数### ...
- 实现输出h264直播流的rtmp服务器 flash直播服务器【转】
实现输出h264直播流的rtmp服务器 RTMP(Real Time Messaging Protocol)是常见的流媒体协议,用来传输音视频数据,结合flash,广泛用于直播.点播.聊天等应用,以及 ...