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只连续的奶牛,那么,这些奶牛就会罢工去开派对:)。因此,现在FJ需要你的帮助,计算FJ可以得到的最大效率,并且该方案中没有连续的超过K只奶牛。

Input

* 第一行:空格隔开的两个整数N和K
* 第二到N+1行:第i+1行有一个整数E_i

Output

* 第一行:一个值,表示FJ可以得到的最大的效率值。

题解:

定义F[i]为前 i-1 只奶牛工作效率的最大值。

sum[i]是Ei的前缀和。

有F[i]=max{F[j]+sum[i-1]-sum[j]} (i-j<k)

可以用单调队列维护 F[j]-sum[j] 。

代码:

#include<cstdio>
using namespace std;
long long sum[100005];
long long f[100005];
long long n,k;
struct N{
    int x;long long w;
    N(int a=0,long long b=0){
        x=a,w=b;
    }
};
struct dddl{
    int h,t;
    N q[100005];
    void insert(N a){
        while(h!=t&&q[t-1].w<=a.w) t--;
        q[t++]=a;
    }
    void pop(int x){
        if(q[h].x==x) h++;
    }
    long long ask(){
        return q[h].w;
    }
}dddl;
int main(){
    scanf("%d%d",&n,&k);
    for(int i=1;i<=n;i++){
        scanf("%lld",&sum[i]);
    }
    k++;
    for(int i=1;i<=n;i++) sum[i]+=sum[i-1];
    dddl.insert(N(0,0));
    for(int i=1;i<=n+1;i++){
        dddl.pop(i-k-1);
        f[i]=dddl.ask()+sum[i-1];
        dddl.insert(N(i,f[i]-sum[i]));
    }
    printf("%lld\n",f[n+1]);
    return 0;
}
时间: 2024-10-11 08:18:00

BZOJ 2442: [Usaco2011 Open]修剪草坪的相关文章

[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

[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

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]修剪草坪 斜率优化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_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 <algorith

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\),所以直接单调队列维护咯! 维护

[bzoj]2442 修剪草坪

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

修剪草坪 HYSBZ - 2442

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

【USACO 2011 Open】修剪草坪(DP)

题目描述 在一年前赢得了小镇的最佳草坪比赛后,FJ 变得很懒,再也没有修剪过草坪.现在,新一轮的最佳草坪比赛又开始了,FJ 希望能够再次夺冠.然而,FJ 的草坪非常脏乱,因此,FJ 只能够让他的奶牛来完成这项工作.FJ 有 N 只排成一排的奶牛,编号为 1...N.每只奶牛的效率是不同的,奶牛 i 的效率为 E_i.靠近的奶牛们很熟悉,因此,如果 FJ 安排超过 K 只连续的奶牛,那么,这些奶牛就会罢工去开派对:).现在 FJ 需要你的帮助,计算 FJ 可以得到的最大效率,并且该方案中没有连续的