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;
    }
    路漫漫兮
  • 相关阅读:
    常用正则
    使用html2canvas 图片 清晰性高 兼容好
    倒计时调用
    多线程实现等待屏(欢迎屏)的实现
    代码生成机器人被360软件管家收录
    代码生成器1.0正式发布
    代码生成器
    代码生成器 - 第一版最终版
    ICSharpCode.TextEditor使用经验
    代码生成器
  • 原文地址:https://www.cnblogs.com/lonely-wind-/p/13264330.html
Copyright © 2011-2022 走看看