zoukankan      html  css  js  c++  java
  • HDU 4193 Non-negative Partial Sums【单调队列】

    题目链接:

    http://acm.hdu.edu.cn/showproblem.php?pid=4193

    题意:

    给定序列,可以把后面的连续的部分移到最前面来,问多少种移法使得最终得到的序列的前i项和均大于等于0(1in)?

    分析:

    先将数组前后拼接起来,记录每个位置的前缀和。然后去找长度为n的滑动窗口,在这个窗口内,要保证前i项和大于等于0,也即区间[i,n+i]之间的找到的最小的前缀和要比a[i1]大。而不涉及修改,这个最小前缀和的获取和维护就利用单调队列即可~

    代码:

    #include<cstdio>
    #include<cstring>
    #include<iostream>
    using namespace std;
    const int maxn = 2e6 + 5;
    int q[maxn], a[maxn];
    int head, rear;
    int n, cnt;
    void inque(int i)
    {
        while(rear >= head && a[q[rear]] >= a[i]) rear--;
        q[++rear] = i;
    }
    void outque(int i)
    {
        if(q[head] < i - n + 1){
            head++;
        }
    }
    int main (void)
    {
        while(scanf("%d", &n) && n){
            head = 0, rear = 0;
            memset(a, 0, sizeof(a));
            memset(q, 0, sizeof(q));
            for(int i = 0; i < n; i++){
                scanf("%d", &a[i]);
                a[n + i] = a[i];
            }
            for(int i = 1; i < 2 * n; i++)
                 a[i] += a[i - 1];
           for(int i = 0; i < n; i++)
                inque(i);
           int cnt = 0;
           for(int i = n; i < 2 * n; i++){
                outque(i);
                inque(i);
                if(a[q[head]] - a[i- n] >= 0)  cnt++;
            }
            printf("%d
    ", cnt);
        }
        return 0;
    }
    /*
    5
    -1 -2 -3 -4 -5
    */
    
  • 相关阅读:
    机器学习概要
    Latex公式压缩
    MATLAB多项式运算
    利用MathType为公式编号并引用
    MATLAB符号对象与符号运算
    MATLAB矩阵运算
    MATLAB绘制函数图
    MATLAB程序控制语句
    MATLAB关系运算符和逻辑运算符
    Raspberry pi之wifi设置-3
  • 原文地址:https://www.cnblogs.com/Tuesdayzz/p/5758689.html
Copyright © 2011-2022 走看看