zoukankan      html  css  js  c++  java
  • 最大子序列和 HDOJ 1003 Max Sum

    题目传送门

    题意:求MCS(最大连续子序列和)及两个端点
    分析:第一种办法:dp[i] = max (dp[i-1] + a[i], a[i]) 可以不开数组,用一个sum表示前i个数字的MCS,其实是一样的。。。类似DP的做法有个名字叫联机算法

       第二种办法:一个前缀记录前i个数字的和,那么ans = sum - mn; mn表示前j个和且和最小

       两种办法都是O (n) 1003就这么难?? 推荐学习资料:六种姿势拿下连续子序列最大和问题  最大子序列和问题

    收获:MCS问题的两种o (n) 的算法,且还有递归的解法 O (nlogn)

    代码1:

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    
    const int N = 1e6 + 10;
    const int INF = 0x3f3f3f3f;
    int a[N];
    
    //O (n)
    void MCS(int n)	{
    	int l = 0, ll = 0, rr = 0;
    	int sum = -INF, mx = -INF;
    	for (int i=1; i<=n; ++i)	{
    		if (sum + a[i] < a[i])	{
    			sum = a[i];	l = i;
    		}
    		else	sum += a[i];
    		if (sum > mx)	{
    			mx = sum;	ll = l, rr = i;
    		}
    	}
    	printf ("%d %d %d
    ", mx, ll, rr);
    }
    
    int main(void)	{
    	int T, cas = 0;	scanf ("%d", &T);
    	while (T--)	{
    		int n;	scanf ("%d", &n);
    		for (int i=1; i<=n; ++i)	scanf ("%d", &a[i]);
    		printf ("Case %d:
    ", ++cas);
    		MCS (n);
    		if (T)	puts ("");
    	}
    
    	return 0;
    }
    

    代码2:

    //O (n) //another
    void MCS(int n)	{
    	int l = 0, ll = 0, rr = 0;
    	int sum = 0, mx = -INF, mn = 0;
    	for (int i=1; i<=n; ++i)	{
    		sum += a[i];
    		if (sum - mn > mx)	{
    			mx = sum - mn;	ll = l;	rr = i;
    		}
    		if (sum < mn)	{
    			mn = sum;	l = i;
    		}
    	}
    	printf ("%d %d %d
    ", mx, ll + 1, rr);
    }
    编译人生,运行世界!
  • 相关阅读:
    学生排序,使用三层优先级
    利用类计算学生成绩和排序
    join()函数
    对象
    015_eclipse开发环境的使用
    013_运算符_算术
    012_变量
    011_jdk7新特性
    010_类型提升问题
    008_浮点数误差问题
  • 原文地址:https://www.cnblogs.com/Running-Time/p/4719011.html
Copyright © 2011-2022 走看看