• hdu1024(dp)


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

    题意:给出一个有n个元素的数组,从其中选出m个不相交区间,求m个区间所有数字和最大为多少

    思路:很明显dp

    我们可以用dp[i][j]存储前i个区间前j个元素和的最大值,最终答案为dp[n][m];

    假设当前为第i个区间,对于第j个元素,我们可以将其加入前i个区间,或者将其单独作为一个区间;

    那么状态转移方程为:

    dp[i][j]=max(dp[i][j-1]+a[j], max(dp[i-1][k])+a[j])  //如果我们将第j个元素加入前i个区间,那么有dp[i][j]=dp[i][j-1]+a[j],

    如果将其单独作为一个区间,那么dp[i][j]=前i-1个区间最大值+a[j],即为dp[i][j]=max(dp[i-1][k])+a[j] (1<=k<=n),max(dp[i-1][k]表示前i-1个区间前j个元素能得到的最大值,那么为了得到分成i-1个区间能得到的最大值我们需要遍历一下k;

    时间复杂度为 O(m*n^2)

    本题的数据范围为1 ≤ x ≤ n ≤ 1,000,000, -32768 ≤ Sx ≤ 32767,  m没有给出范围,也很显然我们上面的算法会超时 ,仔细分析一下我们可以发现max(dp[i-1][k])的值我们在之前已经计算过了,我们只需要开一个一维数组来保持前i-1个区间能得到的最大值即可;

    前面的算法还有一个bug就是如果m稍大一点的话开二维数组会爆内存的,因此,我们需要将其优化成一维数组,用vis[i]表示前i-1个区间能得到的最大和;

    dp[i][j]中的i可以有外面的for循环控制,那么我们用dp[j]代替前面的dp[i][j]即可;

    代码:

     1 #include <iostream>
     2 #include <stdio.h>
     3 #include <string.h>
     4 #include <math.h>
     5 #include <algorithm>
     6 #define MAXN 1000010
     7 #define INF 999999999
     8 using namespace std;
     9 
    10 int vis[MAXN], a[MAXN], dp[MAXN];
    11 
    12 int main(void){
    13     int m, n, mx;
    14     while(~scanf("%d%d", &m, &n)){
    15         memset(vis, 0, sizeof(vis));
    16         memset(dp, 0, sizeof(dp));
    17         for(int i=1; i<=n; i++){
    18             scanf("%d", &a[i]);
    19         }
    20         for(int i=1; i<=m; i++){
    21             mx=-1*INF;
    22             for(int j=i; j<=n; j++){ //注意这里j是从i开始,因为前面已经分了i-1个区间,至少用了i-1个元素嘛
    23                 dp[j]=max(dp[j-1]+a[j], vis[j-1]+a[j]);
    24                 vis[j-1]=mx;
    25                 if(mx<dp[j]){
    26                     mx=dp[j];
    27                 }
    28             }
    29         }
    30         printf("%d
    ", mx);
    31     }
    32     return 0;
    33 }
  • 相关阅读:
    safari调试iphone
    git 本地仓库关联远程仓库
    video 自动播放及循环播放问题
    webpack4系列之【3. webpack4优化记录】
    展示博客
    第三天冲刺
    第二天冲刺
    第一天冲刺
    UML设计
    Alpha项目冲刺
  • 原文地址:https://www.cnblogs.com/geloutingyu/p/6105252.html
Copyright © 2020-2023  润新知