BZOJ_2343_[Usaco2011 Open]修剪草坪 _单调队列_DP

题意:

N头牛,每头牛有一个权值,选择一些牛,要求连续的不能超过k个,求选择牛的权值和最大值

分析:

先考虑暴力DP,f[i] = f[j] + s[i]-s[j+1] (i-j-1<=k 1<=j<i)

意思是我们j+1不要,要j+2到i这部分

发现可以用单调队列优化一下

维护一个单调递减的单调队列,比较时用f[i]-s[i-1]比较

代码:

#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;
#define N 100050
#define LL long long
int n,a[N],Q[N],l,r,k;
LL s[N],f[N],ans;
int main(){
    scanf("%d%d",&n,&k);
    int i;
    for(i = 1;i <= n;i++){
        scanf("%d",&a[i]);
        s[i] = s[i - 1] + a[i];
    }
    r = 1;
    for(i = 1;i <= k;i++){
        f[i] = s[i];
        while(l < r&& f[i] - s[i + 1] >= f[Q[r - 1]] - s[Q[r - 1] + 1]) r--;
        Q[r++] = i;
        ans = max(ans,f[i]);
    }
    for(i = k + 1;i <= n;i++){
        while(l < r&& i - Q[l] - 1 > k) l++;
        f[i] = f[Q[l]] - s[Q[l] + 1] + s[i];
        while(l < r&& f[i] - s[i + 1] >= f[Q[r - 1]] - s[Q[r - 1] + 1]) r--;
        Q[r++] = i;
        ans = max(ans,f[i]);
        // printf("%lld\n",f[i]);
    }
    printf("%lld\n",ans);
}

原文地址:https://www.cnblogs.com/suika/p/8542275.html

时间: 2024-11-13 23:58:46

BZOJ_2343_[Usaco2011 Open]修剪草坪 _单调队列_DP的相关文章

[BZOJ2442][Usaco2011 Open]修剪草坪 dp+单调队列优化

2442: [Usaco2011 Open]修剪草坪 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 1118  Solved: 569[Submit][Status][Discuss] Description 在一年前赢得了小镇的最佳草坪比赛后,FJ变得很懒,再也没有修剪过草坪.现在,新一轮的最佳草坪比赛又开始了,FJ希望能够再次夺冠. 然而,FJ的草坪非常脏乱,因此,FJ只能够让他的奶牛来完成这项工作.FJ有N(1 <= N <= 100,0

P2627 修剪草坪[dp][单调队列]

P2627 修剪草坪 给你一个\(n\)个数字的数组,至多连续取\(k\)个数字,求取出的最大和. 预处理了前缀和之后,一维dp很容易想:\(dp[i] = max(dp[j-1] + sum[j+1,i])\) 用前缀和写就是\(dp[i]=max(dp[j-1]+sum[i]-sum[j])\) 把与\(i\)有关的拿出\(max\),就有\(dp[i]=sum[i]+max(dp[j-1]-sum[j])\) \(j\)能取的是一个固定区间,长度为\(k\),所以直接单调队列维护咯! 维护

bzoj2442[Usaco2011 Open]修剪草坪 单调队列优化dp

2442: [Usaco2011 Open]修剪草坪 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 1159  Solved: 593[Submit][Status][Discuss] Description 在一年前赢得了小镇的最佳草坪比赛后,FJ变得很懒,再也没有修剪过草坪.现在,新一轮的最佳草坪比赛又开始了,FJ希望能够再次夺冠. 然而,FJ的草坪非常脏乱,因此,FJ只能够让他的奶牛来完成这项工作.FJ有N(1 <= N <= 100,0

[BZOJ2442][Usaco2011 Open]修剪草坪

2442: [Usaco2011 Open]修剪草坪 Time Limit: 10 Sec  Memory Limit: 128 MB Submit: 1053  Solved: 526 [Submit][Status][Discuss] Description 在一年前赢得了小镇的最佳草坪比赛后,FJ变得很懒,再也没有修剪过草坪.现在, 新一轮的最佳草坪比赛又开始了,FJ希望能够再次夺冠. 然而,FJ的草坪非常脏乱,因此,FJ只能够让他的奶牛来完成这项工作.FJ有N (1 <= N <= 1

shu_1078 vijos_1091(环城旅行)_单调队列

http://202.121.199.212/JudgeOnline/problem.php?cid=1078&pid=9 分析: a[ i ] :  第i个城市的汽油与到下一个城市距离的差: dis[ i ] : 第i个城市到下一个城市的距离: s[ i ] : 前i个 a[ i ] 的和: 路径 i-->i+n 中间不断油,那么 T= ai + (ai+1)+ ...( ak)  对于任意的 i < k <=i+n, T都要大于0, 即, T= s[ k ]- s[ i-1

BZOJ 2442: [Usaco2011 Open]修剪草坪

Description 在一年前赢得了小镇的最佳草坪比赛后,FJ变得很懒,再也没有修剪过草坪.现在,新一轮的最佳草坪比赛又开始了,FJ希望能够再次夺冠.然而,FJ的草坪非常脏乱,因此,FJ只能够让他的奶牛来完成这项工作.FJ有N(1 <= N <= 100,000)只排成一排的奶牛,编号为1...N.每只奶牛的效率是不同的,奶牛i的效率为E_i(0 <= E_i <= 1,000,000,000).靠近的奶牛们很熟悉,因此,如果FJ安排超过K只连续的奶牛,那么,这些奶牛就会罢工去开

【BZOJ2442】 [Usaco2011 Open]修剪草坪 斜率优化DP

第一次斜率优化. 大致有两种思路: 1.f[i]表示第i个不选的最优情况(最小损失和)f[i]=f[j]+e[i] 显然n^2会T,但是可以发现f的移动情况可以用之前单调队列优化,就优化成O(n)的了. 2.f[i]表示第i个选,第j+1不选的最优情况(最大效率和)f[i]=f[j]+sum[i]-sum[j+1] (i-k-1<=j<=i-1),同样也能单调队列优化成O(n). PS:第一种做法的需要枚举不选最后k个数的情况,但是Min的初值0x7fffffff(max_longint)是会

BZOJ_1342_[Baltic2007]Sound静音问题_单调队列

题意: 给出n个数,求∑[ max{a[i]~a[i+m-1]} - min{a[i]~a[i+m-1]} <= c ] 分析: 滑动窗口 我们维护两个单调队列,分别存最大,最小值 代码: #include <cstdio> #include <cstdlib> #include <cstring> #include <iostream> #include <algorithm> using namespace std; #define N

[bzoj1342][Baltic2007]Sound静音问题_单调队列

Sound静音问题 bzoj-1342 Baltic-2007 题目大意:给定一个n个数的序列,求所有的长度为m的区间,使得区间内最大值减去最小值不超过阈值c. 注释:$1\le n \le 10^6$,$1\le m\le 10^4$. 想法:单调队列裸题. 定长区间最值问题显然可以用单调队列维护. 最后,附上丑陋的代码... ... #include <iostream> #include <cstdio> #include <cstring> #include &