• 求m个不相交子段的和(复杂dp


    题目:给定n,m,求长度为n的数列的m个不相交子列的最大和。

    视状态为dp[i][j]为分成i组以j结尾的最大子列和,状态转移方程为:

    dp[i][j]=max{ A: dp[i][j-1]  , B: max(dp[i-1][i~j-1])   } + a[j];

    A: a[j]与a[j-1]相连组成第i个子列   B:a[j]不与任何子列相连,独自形成第i个子列

    i的移动需要m次循环,j的移动需要n次循环,B中max项的确认需要j-i+1次循环

    时间复杂度可达 n^3,n最大为1000000,dp[i][j]会mle

    优化: dp只与i,i-1状态有关,可以只开一维数组,优化空间

                用premx[j-1]记录上一次外层循环的max(dp[i-1][i~j-1]) 可以免去第三次循环 时间降为n^2

    #include<bits/stdc++.h>
    using namespace std;
    #define MAXN 1000000
    const int inf=0x3f3f3f3f;
    
    int dp[MAXN+10],a[MAXN+10],premx[MAXN+10];
    
    int main(){
         int m,n;
         while(scanf("%d%d",&m,&n)!=EOF){
             for(int i=1;i<=n;i++){
                 scanf("%d",&a[i]);
                 dp[i]=0; premx[i]=0;     //dp,premx:第一行之前0个不相交子列最大和是0
             }
             int mx;
             dp[0]=0; premx[0]=0;
             for(int i=1;i<=m;i++){
                 mx=-inf;
                 for(int j=i;j<=n;j++){
                     dp[j]=max(dp[j-1],premx[j-1])+a[j];
                     premx[j-1]=mx;
                     mx=max(mx,dp[j]);
                 }
             }
    
             printf("%d
    ",mx);
    
         }
    
         return 0;
    }

    参考:https://www.cnblogs.com/kuangbin/archive/2011/08/04/2127085.html

  • 相关阅读:
    构建可靠的系统
    netty详解之reactor模型
    netty详解之io模型
    小明的魔法调度框架之旅
    JAVA版-微信高清语音.speex转.wav格式
    Spring Data JPA 缓存结合Ehcache介绍
    @media print样式 关于table断页
    JBPM学习第6篇:通过Git导入项目
    JBPM学习第5篇:Mysql配置
    JBPM学习第4篇:10分钟熟悉Eclipse
  • 原文地址:https://www.cnblogs.com/-ifrush/p/10460811.html
Copyright © 2020-2023  润新知