Poj2479(&poj2593)(动规)

题意:在一个数组中找出两个不相交的串的的最大和。

解题思路:这是最大连续和的一个变形,不同之处就在于是求两个不相交的串的最大和。容易想到的就是用两个数组来分别记录以i结尾的串最大和和以i开头的最大和,然后固定一个前一个或后一个串,遍历另一个串,找出其中最大的,然后改变前一个串,再找最大的,依次比较最终就得到最大值了,这样做的时间复杂度为O(n2)。

但对于题目给的规模,这样的时间复杂度会超时。所以需要对思路进行改进。可以再用一个数组记录后一个(或前一个)中在i之后的串的最大值,这样固定前一个串时,后面一个串的最大值就可以直接取出,不用在遍历后面一个串了,时间复杂度为O(n)。

poj2593和这个问题一样,只是数据规模和输入输出格式不同,这里只给出poj2479的代码。

代码如下:

#include <iostream>
#include <cstdio>
#include <cstring>

using namespace std;

const int MAXN = 50005;
int a[MAXN], f[MAXN], e[MAXN], me[MAXN];

int main()
{
  int t, n, i, ans;

  scanf("%d", &t);

  while(t--)
  {
      scanf("%d", &n);
      for(i = 0; i < n; i++)
        scanf("%d", &a[i]);

    memset(me, 0, sizeof(me));
    memset(f, 0, sizeof(f));
    memset(e, 0, sizeof(e));  //虽然不需要对数组初始化,但这要形成习惯,避免以后出现问题。

      f[0] = a[0];
      e[n-1] = a[n-1];
      me[n-1] = a[n-1];

      for(i = 1; i < n; i++)  //求以a[i]结尾的最大串
      {
          if(f[i-1] > 0)
          {
              f[i] = f[i-1]+a[i];
          }
          else
          {
              f[i] = a[i];
          }
      }
      for(i = n-2; i > -1; i--) //求以a[i]开头的最大串,同时求出后i个数中的最大串
      {
          if(e[i+1] > 0)
          {
              e[i] = e[i+1]+a[i];
          }
          else
          {
              e[i] = a[i];
          }
          me[i] = max(me[i+1], e[i]);  //记录后i个中最大的串。
      }
      //ans = 0;        //这样初始化导致答案错误,因为ans可能小于0
      ans = f[0]+me[1];  //初始化时最好是第一个可行值,防止上面的情况。
      for(i = 0; i < n-1; i++)
      {
          ans = max(ans, f[i] + me[i+1]);
      }
      printf("%d\n", ans);
  }
}




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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值