zoukankan      html  css  js  c++  java
  • hdu 1024 Max Sum Plus Plus

    https://vjudge.net/problem/HDU-1024

    题意:

    给出一个数m和n,再给出n个数,要求选出m个不相交区间,之后找出这个m个不相交区间中的区间之和最大值。

    思路:

    动态规划,dp[i][j]表示前j个数选了i个区间的最大值,那么dp[i][j]的最大值要么是把当前的a[j]加到第i个区间中,要么是选前i - 1个区间中的最大值,把当前的a[j]作为第i个区间的第一个元素。

    于是这样的转移方程就为dp[i][j] = max(dp[i][j-1] + a[j],dp[i-1][k] + a[j]) (i - 1 <= k <= j - 1)。

    首先,dp[i][j]如果用二维数组的话,i和j的最大值都是1e6,那么肯定空间会爆,所以必须降维优化,我们观察到实际上如果用dp[j]表示取到第j个数的时候的最大,也是可行的。然后时间复杂度的优化,我们可以用一个数组来保存取到第i个区间时取到前 j - 1个数的最大值。

    这样转移方程就变成了dp[j] = max(dp[j-1] + a[j],maxn[j-1] + a[j]),maxn[j - 1] 就是在第i个区间时,取i - 1 到 j - 1个数之中的最大值。

    代码:

     1 #include <stdio.h>
     2 #include <string.h>
     3 #include <algorithm>
     4 using namespace std;
     5 int a[1000005],dp[1000005],maxn[1000005];
     6 
     7 int main()
     8 {
     9     int n,m;
    10     
    11     while (scanf("%d%d",&m,&n) != EOF)
    12     {
    13         for (int i = 1;i <= n;i++)
    14             scanf("%d",&a[i]);
    15         
    16         memset(dp,0,sizeof(dp));
    17         
    18         memset(maxn,0,sizeof(maxn));
    19         
    20         int tmp;
    21         
    22         for (int i = 1;i <= m;i++)
    23         {
    24              tmp = -1e8;
    25             
    26             for (int j = i;j <= n;j++)
    27             {
    28                 dp[j] = max(dp[j-1] + a[j],maxn[j-1] + a[j]);
    29                 
    30                 maxn[j-1] = tmp;//这里保存的是上一个
    31                 
    32                 tmp = max(tmp,dp[j]);
    33             }
    34         }
    35         
    36         printf("%d
    ",tmp);
    37     }
    38     return 0;
    39 }
  • 相关阅读:
    Tomcat常用配置
    java开发规范总结_命名规范
    Android学习笔记(广播机制)
    Java Web 实现Mysql 数据库备份与还原
    interfaces
    windows phone 1
    正在写。。
    Exceptions
    类的非常简单的应用
    say hello
  • 原文地址:https://www.cnblogs.com/kickit/p/7512101.html
Copyright © 2011-2022 走看看