zoukankan      html  css  js  c++  java
  • HDU 1024 Max Sum Plus Plus【DP,最大m子段和】

    题目链接:

    http://acm.hdu.edu.cn/showproblem.php?pid=1024

    题意:

    给定序列,给定m,求m个子段的最大和。

    分析:

    dp[i][j]为以第j个元素结尾的i个子段的和。
    对于每个元素有和前一个元素并在一起构成一个子段,和单独开启一个子段两种可能,状态转移方程

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

    时间复杂度O(mn2)n高达1e6,肯定超时。
    接着可以用滚动数组进行空间和时间的优化。
    直接开一个数组存储这个 dp[i1][k],也就是前j个元素中子段数为i - 1的最大值,用ans记录当前数目子段的最大值,然后子段数不断增加的过程中不断更新。时间复杂度O(nm)
    我觉得ans和数组dp,t都应该long long的,发现int也能A。。。

    代码:

    #include<cstdio>
    #include<cstring>
    #include<iostream>>
    using namespace std;
    #define sa(a) scanf("%d", &a)
    #define sal(a) scanf("%I64d", &a)
    const int maxn = 1e6 + 5, INF = 0x3f3f3f3f;
    int a[maxn];
    long long dp[maxn], t[maxn];
    int main (void)
    {
        int n, m;
        while(~scanf("%d%d", &m, &n)){
            memset(dp, 0, sizeof(dp));
            memset(t, 0, sizeof(t));
            for(int i = 1; i <= n; i++)  sa(a[i]);
            long long ans;
            for(int i = 1; i <= m; i++){
                ans = -INF;
                for(int j = i; j <= n; j++){
                    dp[j] = max(dp[j - 1], t[j - 1])+ a[j];
                    t[j - 1] = ans;
                    ans = max(ans, dp[j]);
                }
            }
            printf("%d
    ", ans);
        }
        return 0;
    }
    /*
    1 2 2 3
    3 3 -3 -3 -3
    */
    
  • 相关阅读:
    hbase 相关
    java 连接 hiveserver2 例子
    ik_max_word ik_smart 区别 和 单字 查询 不到问题
    如何计算地址线和数据线
    golang consistent hash 菜鸟分析
    借助GitHub托管你的项目代码
    PHP性能追踪及分析工具xhprof的安装与使用
    git使用方法
    go开发
    go的websocket实现
  • 原文地址:https://www.cnblogs.com/Tuesdayzz/p/5758679.html
Copyright © 2011-2022 走看看