zoukankan      html  css  js  c++  java
  • CF1197D Yet Another Subarray Problem

    DP

    首先可以发现要增加$m$个元素才对答案产生影响

    那么记$dp[i][j]$为前$i$个且连续了$j$个元素的最大值

    然后就是转移

    一开始我对于每一个$i$,$j$都去枚举前$m$个元素进行转移,但这是不必要的

    后来$jinzy$大佬将我的$dp$转移简化了,从原来$O(m)$的转移简化到了$O(1)$

    因为确定了i和j就可以确定这串元素的开头集合,那么动态规划的性质

    只要找出之前的元素进行转移即可,那么对于前面的元素可以任意选取

    $jzy$大佬选了前1个元素$dp$

    $jzy$大佬的程序,还有他的博客

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    using namespace std;
    typedef long long ll;
    const ll inf=200000000000000;
     
    int n,m;
    ll ans=0,dp[300005][20],sum[300005],a[300005],k;
     
    int main()
    {
        scanf("%d%d%lld",&n,&m,&k);
        for(int i=1;i<=n;i++)
        {
            scanf("%lld",&a[i]);
            sum[i]=sum[i-1]+a[i];
        }
        for(int i=1;i<=n;i++)
        {
            for(int j=0;j<=m;j++) dp[i][j]=-inf;
        }
        dp[1][1]=a[1]-k; 
        for(int i=2;i<=n;i++)
        {
            dp[i][1]=a[i]-k;
            for(int j=1;j<=min(i,m);j++)
            {
                if(j==1) dp[i][j]=max(dp[i][j],dp[i-1][m]+a[i]-k);//其实只要从前1个元素转移过来
                else dp[i][j]=max(dp[i][j],dp[i-1][j-1]+a[i]); 
            }
        }
        for(int i=1;i<=n;i++)
        {
            for(int j=1;j<=m;j++) ans=max(ans,dp[i][j]);
        }
        cout<<ans<<endl;
        return 0;
    }

    我当时写的暴力dp

    #include <bits/stdc++.h>
    #define ll long long
    #define inf 1e18
    using namespace std;
    const ll MAXN=3*1e5+100;
    ll n,m,k,dp[MAXN][12],a[MAXN],sum[MAXN];
    int main()
    {
        scanf("%lld%lld%lld",&n,&m,&k);
        for (ll i=1;i<=n;i++)
          scanf("%lld",&a[i]);
        for (ll i=1;i<=n;i++)
          sum[i]=sum[i-1]+a[i];
        for (ll i=1;i<=n;i++)
        {
            for (ll j=1;j<=m;j++)
              dp[i][j]=-inf;
        }
        dp[1][1]=a[1]-k;
        for (ll i=2;i<=n;i++)
        {
            dp[i][1]=a[i]-k;
            for (ll j=1;j<=min(m,i);j++)
            {
                for (ll p=max((ll)1,i-m);p<i;p++)
                {
                    if (j>p)
                      continue;
                    int d;
                    d=i-p;
                    if (j+d>m)
                      dp[i][j+d-m]=max(dp[i][j+d-m],dp[p][j]+sum[i]-sum[p]-k);
                    else
                      dp[i][j+d]=max(dp[i][j+d],dp[p][j]+sum[i]-sum[p]);
                }
            }
        }
        ll ans=0;
        for (ll i=1;i<=n;i++)
        {
            for (ll j=1;j<=min(m,i);j++)
              ans=max(ans,dp[i][j]);
        }
        printf("%lld
    ",ans);
    }

    orz jzy大佬

  • 相关阅读:
    .net core读取appsettings.config中文乱码问题
    vs2017错误:当前页面的脚本发生错误
    VS Code中无法识别npm命令
    Visual Studio报错/plugin.vs.js,行:1074,错误:缺少标识符、字符串或数字
    记录一次在生成数据库服务器上出现The timeout period elapsed prior to completion of the operation or the server is not responding.和Exception has been thrown by the target of an invocation的解决办法
    Java集合框架
    java hash表
    Java Dictionary 类存储键值
    java数据结构 栈stack
    java封装
  • 原文地址:https://www.cnblogs.com/huangchenyan/p/11254667.html
Copyright © 2011-2022 走看看