• HDU1244:Max Sum Plus Plus Plus


    题目链接:Max Sum Plus Plus Plus

    题意:在n个数中取m段数使得这m段数之和最大,段与段之间不能重叠

    分析:见代码

    //dp[i][j]表示前i个数取了j段的最大值
    //状态转移:dp[i][j]=max(dp[k][j-1]+(sum[k+l[j]-sum[k]或者sum[i]-sum[i-l[j]) (0<=k<=i-l[j]) 
    // 这种做法是O(n^2)的 
    //如果改成O(n)的呢?
    //需要加一个数组max_dp[i][j]表示前i个数取j段的dp最大值
    //如果i>=l[j],dp[i][j]=max(dp[i][j],s[i-l[j]][j-1]+sum[i]-sum[i-l[j]]
    //然后每次更新 max_len[i][j]=max(max_dp[i-1][j],dp[i][j])
    //最后取dp[i][m]的最大值
    //PS:说这道题是水题的人真的好好想过了吗?纵然你DP很厉害,也不能随便看看题目,发现是水题,然后抄了网上的代码,就完事了,
    //真的有必要去多想想题目,百度出来的题解,一个抄一个,真的有意思?!! 
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    
    int n,m,l[21],sum[1010],dp[1010][21],max_dp[1010][21];
    
    int main()
    {
        while(scanf("%d",&n),n)
        {
            scanf("%d",&m);
            memset(dp,0,sizeof(dp));
            memset(max_dp,0,sizeof(max_dp));
            for(int i=1;i<=m;++i) scanf("%d",l+i);
            for(int i=1;i<=n;++i)
            {
                scanf("%d",sum+i);sum[i]+=sum[i-1];
            }
            /* 
            //O(n)
            for(int i=1;i<=n;++i)for(int j=1;j<=m;++j)for(int k=0;k<=i-l[j];k++)
            dp[i][j]=max(dp[i][j],dp[k][j-1]+sum[k+l[j]]-sum[k]);
            */ 
            //O(1)
            for(int i=1;i<=n;++i)for(int j=1;j<=m;++j)
            {
                if(i>=l[j]) dp[i][j]=max(dp[i][j],max_dp[i-l[j]][j-1]+sum[i]-sum[i-l[j]]);
                 max_dp[i][j]=max(max_dp[i-1][j],dp[i][j]);
            }
            int ret=0;
            for(int i=1;i<=n;++i) ret=max(ret,dp[i][m]);
            printf("%d
    ",ret);
        }
    } 
    View Code
  • 相关阅读:
    from __future__ import *
    每日一题力扣102
    每日一题力扣228
    每日一题力扣409
    每日一题力扣135 分糖果 中级
    【K短路】牛慢跑
    【2021-06-12】只有团队作战,才能更好生存
    【2021-06-11】不怕事情被砸,就怕团队不愿意承压
    【2021-06-10】压力需主动承受,才能进步
    【2021-06-09】日记和睡觉治疗法
  • 原文地址:https://www.cnblogs.com/chendl111/p/5831702.html
Copyright © 2020-2023  润新知