zoukankan      html  css  js  c++  java
  • HDU-1024Max Sum Plus Plus(最大m段子序列和-DP)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1024

    题目大意:给m 和n个数,将n个数分为m段,不交叉,求m段和的最大值。

    Sample Input

    1 3 1 2 3
    2 6 -1 4 -2 3 -2 3

    Sample Output

    6
    8

    emmm,先想容易的,我们应该很容易想到设置状态$dp[i][j]$表示在第$j$个字段末尾分为$i$段的最大值,那么则有$dp[i][j]=max(dp[i][j-1]+a[j],pre[i-1][j-1]+a[j])$也就是该数字要么和之前的数字连接起来也就是$dp[i][j-1]+a[j]$,要么自成一段,就是$pre[i-1][j-1]+a[j]$,其中$pre[i][j]$表示在$j$之前分为$i$段的最大值是多少。

    那么我们看到,实际上用到的只有上一段,也就是说我们完全可以直接将其化为滚动数组。那么代码也就出来了

    以下是AC代码:

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <cmath>
    using namespace std;
    
    typedef long long ll;
    const int mac=1e6+10;
    const ll inf=1e15+10;
    
    int a[mac];
    ll dp[mac],pre[mac];
    
    int main(int argc, char const *argv[])
    {
        int m,n;
        while (~scanf ("%d%d",&m,&n)){
            for (int i=1; i<=n; i++)
                scanf ("%d",&a[i]);
            memset(dp,0,sizeof dp);
            memset(pre,0,sizeof pre);
            dp[0]=-inf;
            ll mi;
            for (int i=1; i<=m; i++){
                mi=-inf;
                for (int j=i; j<=n; j++){
                    dp[j]=max(dp[j-1]+a[j],pre[j-1]+a[j]);
                    pre[j-1]=mi;
                    mi=max(mi,dp[j]);
                }
            }
            printf("%lld
    ",mi);
        }
        return 0;
    }
    路漫漫兮
  • 相关阅读:
    D. Constructing the Array
    B. Navigation System
    B. Dreamoon Likes Sequences
    A. Linova and Kingdom
    G. Special Permutation
    B. Xenia and Colorful Gems
    Firetrucks Are Red
    java getInstance()的使用
    java 静态代理和动态代理
    java 类加载机制和反射机制
  • 原文地址:https://www.cnblogs.com/lonely-wind-/p/13264330.html
Copyright © 2011-2022 走看看