• [XJOI]最大K段和 题解


    题目:XJOI335

    传送门 [ >XJOI< ]

    重要提示:您的膜法等级必须达到3级6段才可使用本传送门,否则您会被小猫痛扁

    因为博主太懒,不提供题面(QAQ)...

    很容易想到使用DP,设f[i][j]为第i个段,第i-1段以j-1为终点的最大可能和。

    于是引出递推式:f[i][j] = max(f[i-1][k]) 其中k枚举且k<j。

    然后优化DP,使用一个数组来保存max(f[i-1][k])的值省去枚举。

    发现该数组必须使用交替的方式来保证需要的值不被覆盖。

    最后一步发现f数组的第一维可以省去,空间不会溢出,得解!

    附上一段垃圾代码:

    #include <cstdio>
    #include <queue>
    #include <cstring>
    #define ll long long
    using namespace std;
    ll p[5005],f[5005],Max[2][5005];
    int main()
    {
        int n, m, k, i;
        scanf("%d %d %d",&n,&m,&k);
        for (i=1;i<=n;i++)scanf("%lld",&p[i]);
        ll max_ans=0;
        for (i=1;i<=k;i++){
            int j;Max[0][0] = 0;
            for (j=(i-1)*m+1;j<=(n-m+1);j++){
                ll tmp = 0;
                for (int K=0;K<m;K++)tmp+=p[j+K];
                if (j - m > 0)f[j]=Max[0][j - m]+tmp;else f[j]=tmp;
                if (f[j]>Max[1][j-1]||j==((i-1)*m+1))Max[1][j]=f[j]; else Max[1][j]=Max[1][j-1];
                if (i==k&&f[j]>max_ans)max_ans=f[j];
            }
            memset(Max[0],0,sizeof(Max[0]));
            for (j=(i-1)*m+1;j<=(n-m+1);j++)Max[0][j]=Max[1][j];
        }
        printf("%lld",max_ans);
        return 0; 
    }

    别问我为什么要压行,XJ老是拦截(QWQ),我也没办法啊。

  • 相关阅读:
    Java之内部类
    java之对象的前世今生
    java之继承
    java之接口
    何为大学 大学何为?
    丁香般的姑娘
    MySQL创建数据库与创建用户以及授权
    CentOS6.8手动安装MySQL5.6
    linux 修改myql 编码配置等信息参考
    Centos6.8 Mysql5.6 安装配置教程
  • 原文地址:https://www.cnblogs.com/linzhengmin/p/9446194.html
Copyright © 2020-2023  润新知