POJ 2479 Maximum sum & POJ 2573 Max Sequence (DP,最大连续子串和)

POJ 2479

题意:给一个数列,求任意两个子序列的包含元素的和的最大值,两个子序列无公共部分。

思路:

dp1[i]表示第一个元素a[1]到a[i]的最大子段和,状态转移方程是dp1[i] = max(dp1[i-1]+a[i],a[i]);//不理解最大子段和方程的可以参考最大子段和问题

dp2[i]表示末一个元素a[n]到a[i]的最大子段和,状态转移方程是dp2[i] = max(dp2[i+1]+a[i],a[i]);

再用ans1[i]表示max{dp1[1],dp1[2],...,dp1[i]},用ans2[i]表示max{dp2[n],dp2[n-1],...,dp2[i]},

dp1[i]表示以第i个数结尾的区间最大和,ans1[i]表示到第i个数为止的最大区间和(不一定以第i个数结尾

ans1[i]+ans2[i+1]即表示分割点i左边最大区间和与右边最大区间和之和//我才没晕呢TT

再枚举分割点即可。


code:

/*
*Author : novicer
*Created Time : 2015-07-21 18:37:25
*File name : poj2479.cpp
*/

#include<iostream>
#include<sstream>
#include<fstream>
#include<vector>
#include<list>
#include<deque>
#include<queue>
#include<stack>
#include<map>
#include<set>
#include<bitset>
#include<algorithm>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cctype>
#include<cmath>
#include<ctime>
#include<iomanip>
using namespace std;
const double eps(1e-8);
const int inf = 1000000;
typedef long long lint;

#define cls(a) memset(a,0,sizeof(a))
#define rise(i,a,b) for(int i = a ; i <= b ; i++)
#define fall(i,a,b) for(int i = a ; i >= b ; i--)

const int maxn = 50000 * 2 + 5;
int a[maxn];
int dp1[maxn];
int dp2[maxn];
int ans1[maxn];
int ans2[maxn];
int t;

void solve(){
    int t;
    scanf("%d",&t);
    while(t--){
        int n;
        scanf("%d",&n);
        cls(a);cls(dp1);cls(dp2);cls(ans1);cls(ans2);
        for(int i = 1 ; i <= n ; i++) scanf("%d",&a[i]);
        dp1[1]  = a[1];
        for(int i = 2 ; i <= n ; i++) dp1[i] = max(dp1[i-1]+a[i] , a[i]);
        ans1[1] = a[1];
        for(int i = 2 ; i <= n ; i++) ans1[i] = max(ans1[i-1] , dp1[i]);
        dp2[n] = a[n];
        for(int i = n -1 ; i >= 1 ; i--) dp2[i] = max(dp2[i+1]+a[i] , a[i]);
        ans2[n] = a[n];
        for(int i = n -1 ; i >= 1 ; i--) ans2[i] = max(ans2[i+1] , dp2[i]);
        int ans = -inf;
        for(int i = 1 ; i <= n - 1 ; i++) ans = max(ans , ans1[i]+ans2[i+1]);
        printf("%d\n",ans);
    }
}
int main(){
//  freopen("input.txt","r",stdin);
//  freopen("output.txt","w",stdout);
    solve();
    return 0;
}

POJ 2593

题意:同上题,格式范围略有改动。

思路:做完上一题顺手A了它吧:)

code:

/*
*Author : novicer
*Created Time : 2015-07-21 19:37:25
*File name : poj2593.cpp
*/

#include<iostream>
#include<sstream>
#include<fstream>
#include<vector>
#include<list>
#include<deque>
#include<queue>
#include<stack>
#include<map>
#include<set>
#include<bitset>
#include<algorithm>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cctype>
#include<cmath>
#include<ctime>
#include<iomanip>
using namespace std;
const double eps(1e-8);
const int inf = 1000000;
typedef long long lint;

#define cls(a) memset(a,0,sizeof(a))
#define rise(i,a,b) for(int i = a ; i <= b ; i++)
#define fall(i,a,b) for(int i = a ; i >= b ; i--)

const int maxn = 1000000 * 2 + 5;
int a[maxn];
int dp1[maxn];
int dp2[maxn];
int ans1[maxn];
int ans2[maxn];
int n;

void solve(){
    while(scanf("%d",&n)&&n){
        cls(a);cls(dp1);cls(dp2);cls(ans1);cls(ans2);
        for(int i = 1 ; i <= n ; i++) scanf("%d",&a[i]);
        dp1[1]  = a[1];
        for(int i = 2 ; i <= n ; i++) dp1[i] = max(dp1[i-1]+a[i] , a[i]);
        ans1[1] = a[1];
        for(int i = 2 ; i <= n ; i++) ans1[i] = max(ans1[i-1] , dp1[i]);
        dp2[n] = a[n];
        for(int i = n -1 ; i >= 1 ; i--) dp2[i] = max(dp2[i+1]+a[i] , a[i]);
        ans2[n] = a[n];
        for(int i = n -1 ; i >= 1 ; i--) ans2[i] = max(ans2[i+1] , dp2[i]);
        int ans = -inf;
        for(int i = 1 ; i <= n - 1 ; i++) ans = max(ans , ans1[i]+ans2[i+1]);
        printf("%d\n",ans);
    }
}
int main(){
//  freopen("input.txt","r",stdin);
//  freopen("output.txt","w",stdout);
    solve();
    return 0;
}


  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值