poj2479 Maximum sum (dp)

poj2479 Maximum sum (dp)

题意:k组数据,每组开始一个n代表n个数字,要求这些数字中不连续不重合不相交的两个子串和的最大值、


思路:显然是一个dp,对两端进行dp,找到以i为结尾的子串和的最大值和以i为开头的子串和的最大值,然后再开个数组rmx存储i及其之后的子串和的最大值,再i到n用i结尾的子串和的最大值和rmx相加找最大值即可。最大连续子串和的变式,还是蛮经典的,虽然不难(=。=)

AC代码:

#include<stdio.h>
#include<string.h>
#include<iostream>
#include<map>
#include<math.h>
#include<vector>
#include<queue>
#include<stack>
#include<algorithm>
#define INF 0x3F3F3F3F
#define endl '\n'
#define pb push_back
#define css(n) cout<<setiosflags(ios::fixed)<<setprecision(n); 
#define sd(a) scanf("%d",&a)
#define sld(a) scanf("%lld",&a)
#define m(a,b) memset(a,b,sizeof a)
#define p_queue priority_queue
using namespace std;
typedef long long ll;
const int maxn=50005;
int n,m;
int t;
double a,b;
int arr[maxn];
int dp1[maxn]; //dp1[i]是以i为结尾的最大子串和 
int dp2[maxn];//dp2[i]是以i为开头的最大子串和 
int rmx[maxn];//rmx[i]是i以后的最长连续子串和 
int main()
{
	sd(t);
	while(t--)
	{
		m(dp1,0);
		m(dp2,0);
		m(arr,0); 
		m(rmx,0);
		sd(n);
		for(int i=1;i<=n;i++)
		{
			scanf("%d",&arr[i]);
		}
		dp1[1]=arr[1];
		dp2[n]=arr[n];
		for(int i=2;i<=n;i++)
		{
			dp1[i]=max(dp1[i-1]+arr[i],arr[i]);
		}
		for(int i=n-1;i>=1;i--)
		{
			dp2[i]=max(dp2[i+1]+arr[i],arr[i]);
		}
	//	int mx=0;
		rmx[n]=dp2[n];
		for(int i=n-1;i>=1;i--)
		{
			rmx[i]=max(rmx[i+1],dp2[i]);
		}
		int mx=-INF;//dp中的mx一定要初始化为负数。 
		for(int i=2;i<=n;i++)
		{
			mx=max(dp1[i-1]+rmx[i],mx);//两者不可以重合,所以是i-1和i 
		}
		printf("%d\n",mx);
	 } 
	return 0;
} 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值