• Codeforces 1197D Yet Another Subarray Problem(前缀和+暴力统计)


    题目链接:http://codeforces.com/problemset/problem/1197/D

    题目大意:给出一列数组和两个常数m,k,然后定义一段子序列的cost等于该段子序列各元素之和减去该段长度与m之商的向上取整的值与k的乘积。求任取一段连续子序列所能得到的最大的cost。(ps:可以取空集,此时子序列的cost为0)

    思路:因为涉及到区间和的操作,就可以使用前缀和预处理,把On的查询简化为O1。由题目那条特别注释可以得到最终答案必定大于等于0,因为当取非空集得到的cost都小于0时我们可以取一个空集的cost也就是0作为最大值,所以就不必在初始化的时候把某些数组初始化为-inf这样麻烦的数字。

    然后,cost的计算式中的(r-l+1)/m的向上取整近似于对该子序列进行分块,未满m的一律按一块计算。因此我们可以以小于等于m为一块来统计某个点以前(包含)的最大值,而题目数据量并不大,我们可以直接暴力统计。

    #include<iostream>
    #include<cstdio>
    #include<set>
    #include<stdio.h>
    #include<string.h>
    #include<math.h>
    #include<vector>
    #include<stdlib.h>
    #include<queue>
    #include<algorithm>
    #include<map>
    #include<stack>
    using namespace std;
    long long a[300005];
    long long f[300005];
    int n,m,k;
    int main()
    {
        scanf("%d%d%d",&n,&m,&k);
        for(int i=1;i<=n;i++)
        {
            scanf("%I64d",&a[i]);
            a[i]+=a[i-1];
        }
        long long ans=0;
        for(int i=1;i<=n;i++)
        {
            for(int j=i;j>=1&&j>=i-m+1;j--)
            {
                f[i]=max(a[i]-a[j-1]-k,f[i]);
            }
            if(i-m>0)
            {
                f[i]=max(a[i]-a[i-m]+f[i-m]-k,f[i]);//如果前面的点i-m有定义并且加上它的值更大的话(也就是两段可以连起来得到更大的cost),将两段的值合并到后一段上继续统计
            }
            ans=max(ans,f[i]);
        }
        printf("%I64d
    ",ans);
        return 0;
    }
  • 相关阅读:
    HQueue_Install_In_Ubuntu
    win10_64_ssh连接linux
    win10防火墙服务灰色解决办法
    打开houdini软件的脚本
    houdini_license_sever start and off
    Java关于Object类中equal方法的理解
    Java关于Object类中equal方法的理解
    单源最短路径
    单源最短路径
    最小生成树
  • 原文地址:https://www.cnblogs.com/forever3329/p/11231679.html
Copyright © 2020-2023  润新知