zoukankan      html  css  js  c++  java
  • hdu 1024 最大M子段dp

    题目:

    Max Sum Plus Plus

    Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
    Total Submission(s): 27299    Accepted Submission(s): 9499


    Problem Description
    Now I think you have got an AC in Ignatius.L's "Max Sum" problem. To be a brave ACMer, we always challenge ourselves to more difficult problems. Now you are faced with a more difficult problem.

    Given a consecutive number sequence S1, S2, S3, S4 ... Sx, ... Sn (1 ≤ x ≤ n ≤ 1,000,000, -32768 ≤ Sx ≤ 32767). We define a function sum(i, j) = Si + ... + Sj (1 ≤ i ≤ j ≤ n).

    Now given an integer m (m > 0), your task is to find m pairs of i and j which make sum(i1, j1) + sum(i2, j2) + sum(i3, j3) + ... + sum(im, jm) maximal (ix ≤ iy ≤ jx or ix ≤ jy ≤ jx is not allowed).

    But I`m lazy, I don't want to write a special-judge module, so you don't have to output m pairs of i and j, just output the maximal summation of sum(ix, jx)(1 ≤ x ≤ m) instead. ^_^
     
    Input
    Each test case will begin with two integers m and n, followed by n integers S1, S2, S3 ... Sn.
    Process to the end of file.
     
    Output
    Output the maximal summation described above in one line.
     
    Sample Input
    1 3 1 2 3 2 6 -1 4 -2 3 -2 3
     
    Sample Output
    6 8
    Hint
    Huge input, scanf and dynamic programming is recommended.
    与求最大连续子段略有不同,此题目要求求出m个连续子段的sum,且使得sum尽量大;
    考虑状态转移方程:f{i,j}表示前j个元素分为i段的最大值,则有  f{i,j}=max{f{i,j-1},max{i-1,k}}+a[j],(i-1<=k<j);
    两种决策:
    -1-:  前j个元素分为i段切最后一段以a结尾;
    -2-:aj独自占一段,剩下的i-1段选前k(i-1<=k<j)个元素的i-1段中的最大值
    n为100w考虑使用滚动数组,pre[j]保存上一个i对应的j的的最大值,dp[j]为当前正在计算的i的j的最大值;
    代码:

    #include<bits/stdc++.h>
    using namespace std;
    const int inf=999999999;
    int dp[1000005],a[1000005],pre[1000005];
    int main()
    {
    int n,m,i,j,k,t;
    while (cin>>m>>n){int maxn=-inf;t=0;
    memset(dp,0,sizeof(dp));
    memset(pre,0,sizeof(pre));
    for (i=1;i<=n;i++) scanf("%d",&a[i]);

    for (i=1;i<=m;i++){
    maxn=-inf;                                              //每一轮开始都将maxn初始化
    for (j=i;j<=n;j++){
    dp[j]=max(pre[j-1],dp[j-1])+a[j];             //先使用在更新上一轮的值
    pre[j-1]=maxn;                                         //此处很重要,不可写成下文注释的形式,因为一旦那样写下一个j计算时用到的j-1变成了本轮的最大值的意思,概念就变了

    if (maxn<dp[j]) maxn=dp[j];
    //pre[j]=maxn;
    }
    //for(int l=0;l<=n;l++) cout<<pre[l]<<" ";
    //cout<<endl;
    }
    cout<<maxn<<endl;
    }
    return 0;
    }

  • 相关阅读:
    ssh登录 The authenticity of host 192.168.0.xxx can't be established. 的问题
    Linux学习安装
    linux中的虚拟环境工具
    linux 文件目录权限
    PHP利用百度ai实现文本和图片审核
    Laravel + Swoole 打造IM简易聊天室
    Mysql索引降维 优化查询 提高效率
    Nginx支持比Apache高并发的原因
    网站高并发解决方案(理论知识)
    mysql大量数据分页查询优化-延迟关联
  • 原文地址:https://www.cnblogs.com/zzqc/p/6412848.html
Copyright © 2011-2022 走看看