zoukankan      html  css  js  c++  java
  • 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;
    }
  • 相关阅读:
    scan design rules
    scan cell
    DFT basics
    测试性分析
    DFT设计绪论
    clock gate cell
    Linux命令
    Multi-voltage和power gating的实现
    Power Gating的设计(架构)
    Power Gating的设计(模块二)
  • 原文地址:https://www.cnblogs.com/forever3329/p/11231679.html
Copyright © 2011-2022 走看看