zoukankan      html  css  js  c++  java
  • HDU 1024 Max Sum Plus Plus

    本题的大致意思为给定一个数组,求其分成m个不相交子段和最大值的问题。

    读完题就能看出要用DP,但是因为m的范围没有限定,= =加上自己太菜不知道怎么写, 总之先膜拜大佬http://www.cnblogs.com/kuangbin/archive/2011/08/04/2127085.html

    读完大佬的代码还是有点懵,用自己容易理解的方式 稍微记录一下。

    设dp[i][j]为,分为i段的时候,到第j个数字为止,且包含第j个数字的最大值。

    进行状态转移的时候,当我们访问到第j个数字,我们需要判断它是独立成组,还是包含在已有的段内。

    所以dp[i][j]=max(dp[i][j-1]+a[j],max(dp[i-1][k])+a[j])  (i-1<=k<=j-1)

    但是本题如果直接开双数组的话(n和m会达到的最大值太大),会编译失败。仔细观察的话,可以发现只与该段和前一段有关

    所以我们每次只需要记录最近的两段即可,通过滚动数组进行优化。

    本题用cin输入的话 耗时是比scanf多了近一倍    ,看了下别人的博客学到了一个好方法就是在该函数里面加std::ios::sync_with_stdio(false);  cin用时就会减少

    另外,这个算法的复杂度是O(mn),题目中的m没有给出来,但测试数据中是一个较小的值(1000以下),所以能用这种方法AC。

    #include <cstdio>
    #include <iostream>
    #include <algorithm>
    #include <cmath>
    #include <map>
    #include <cstring>
    using namespace std;
    typedef long long LL;
    const int MAXN=1e6+10;
    const LL INF=1e18;
    LL dp[MAXN];
    LL a[MAXN];
    LL maxx[MAXN];
    int main()
    {
        int m,n;
        LL tmp;
        while(scanf("%d%d",&m,&n)!=EOF)
       {
           if(m>100)while(1);
           memset(dp,0,sizeof(dp));
           memset(maxx,0,sizeof(maxx));
          for(int i=1;i<=n;i++)
            scanf("%lld",&a[i]);
    
          for(int i=1;i<=m;i++)
          {
              tmp=-INF;
              for(int j=i;j<=n;j++)
              {
                dp[j]=max(dp[j-1]+a[j],maxx[j-1]+a[j]);
                maxx[j-1]=tmp;//记录到j-1为止的最大值,留给下一段使用。
                tmp=max(dp[j],tmp);//记录该段目前为止的最大值,进行maxx数组的更新操作。
              }
          }
          printf("%lld
    ",tmp);
       }
    
        return 0;
    }

    ---恢复内容结束---

  • 相关阅读:
    Excel Rendering Limitations
    Output Caching and VaryByParam, VaryByCustom
    ajaxToolkit:AutoCompleteExtender 使用键值对
    Sql Server 2005 存储过程分页
    WEB前端优化
    processModel Element in Machine.config
    如何监测虚拟内存
    MemoryLimit Tuning (ASP.NET v1.1)
    缓存之SqlDependency
    SQL产生随机字符串
  • 原文地址:https://www.cnblogs.com/a249189046/p/6624928.html
Copyright © 2011-2022 走看看