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

    这题的意思就是取m个连续的区间,使它们的和最大,下面就是建立状态转移方程

    dp[i][j]表示已经有 i 个区间,最后一个区间的末尾是a[j]   

    那么dp[i][j]=max(dp[i][j-1]+a[j],max(dp[i-1][1..j-1])+a[j])

    看数据范围,1e6 肯定开不下数组,观察发现,dp[i][j]仅和dp[i][j-1]和dp[i-1][1..j-1]中最大值有关,即只和dp[i-1]有关

    所以开滚动数组求解   复杂度可以通过开数组mmax[j]表示dp[i-1][1..j-1]中最大值,这个数组可以同时更新,这样复杂度降到O(mn)

    然后,我觉得肯定是m比较小,要不然肯定也是超时啊QAQ......

    #include<iostream>
    #include<cstdio>
    #include<cstdlib>
    #include<cmath>
    #include <algorithm>
    #include<cstring>
    using namespace std;
    const int maxn=1000005;
    const int INF=0x7fffffff;
    typedef long long sum[maxn];
    int a[maxn],dp[maxn],mmax[maxn];
    int main()
    {
        int n,m;
        while(~scanf("%d%d",&m,&n))
        {
            for(int i=1; i<=n; ++i)
                scanf("%d",&a[i]);
            int ans=-INF;
            memset(mmax,0,sizeof(mmax));
            for(int i=1; i<=m; ++i)
            {
                int cc=-INF;
                ans=-INF;
                for(int j=i; j<=n; ++j)
                {
                    dp[j]=max(dp[j-1]+a[j],mmax[j-1]+a[j]);
                    mmax[j-1]=cc;
                    cc=max(cc,dp[j]);
                }
                ans=max(ans,cc);
            }
            printf("%d
    ",ans);
        }
        return 0;
    }
    View Code
  • 相关阅读:
    T-sql 中 truncate 、delete与drop操作数据库的区别
    poj -3070 Fibonacci (矩阵快速幂)
    给定一个0-1串,请找到一个尽可能长的子串,其中包含的0与1的个数相等。
    最长的循环节
    大组合数取模
    n个点中求任意两点组成斜率的最大值
    csu
    csu
    poj
    hdu
  • 原文地址:https://www.cnblogs.com/shuguangzw/p/4993256.html
Copyright © 2011-2022 走看看