首页 > 其他分享 >1087. 修剪草坪

1087. 修剪草坪

时间:2022-12-06 22:46:43浏览次数:70  
标签:1087 修剪 int 草坪 FJ 奶牛 define

题目链接

1087. 修剪草坪

在一年前赢得了小镇的最佳草坪比赛后,FJ 变得很懒,再也没有修剪过草坪。

现在,新一轮的最佳草坪比赛又开始了,FJ 希望能够再次夺冠。

然而,FJ 的草坪非常脏乱,因此,FJ 只能够让他的奶牛来完成这项工作。

FJ 有 \(N\) 只排成一排的奶牛,编号为 \(1\) 到 \(N\)。

每只奶牛的效率是不同的,奶牛 \(i\) 的效率为 \(E_i\)。

编号相邻的奶牛们很熟悉,如果 FJ 安排超过 \(K\) 只编号连续的奶牛,那么这些奶牛就会罢工去开派对。

因此,现在 FJ 需要你的帮助,找到最合理的安排方案并计算 FJ 可以得到的最大效率。

注意,方案需满足不能包含超过 \(K\) 只编号连续的奶牛。

输入格式

第一行:空格隔开的两个整数 \(N\) 和 \(K\);

第二到 \(N+1\) 行:第 \(i+1\) 行有一个整数 \(E_i\)。

输出格式

共一行,包含一个数值,表示 FJ 可以得到的最大的效率值。

数据范围

\(1 \le N \le 10^5\),
\(0 \le E_i \le 10^9\)

输入样例:

5 2
1
2
3
4
5

输出样例:

12

样例解释

FJ 有 5 只奶牛,效率分别为 1、2、3、4、5。

FJ 希望选取的奶牛效率总和最大,但是他不能选取超过 2 只连续的奶牛。

因此可以选择第三只以外的其他奶牛,总的效率为 1 + 2 + 4 + 5 = 12。

解题思路

单调队列优化dp

本题等价于选择权重和最小的数,使得不存在连续 \(k+1\) 个数没有被选中

  • 状态表示:\(f[i]\) 表示选择第 \(i\) 个数,且前 \(i\) 个数中连续 \(k+1\) 必须有一个数被选中

  • 状态计算:对于当前数是必选的,维护一个滑动窗口,滑动窗口大小为 \(k+1\)(针对前 \(i-1\) 个数而言),即要在滑动窗口中找权值最小的 \(f[j]\),更新 \(f[i]\),则有 \(f[i]=a[i]+f[j]\)

  • 时间复杂度:\(O(n)\)

代码

// Problem: 修剪草坪
// Contest: AcWing
// URL: https://www.acwing.com/problem/content/description/1089/
// Memory Limit: 64 MB
// Time Limit: 1000 ms
// 
// Powered by CP Editor (https://cpeditor.org)

// %%%Skyqwq
#include <bits/stdc++.h>
 
//#define int long long
#define help {cin.tie(NULL); cout.tie(NULL);}
#define pb push_back
#define fi first
#define se second
#define mkp make_pair
using namespace std;
 
typedef long long LL;
typedef pair<int, int> PII;
typedef pair<LL, LL> PLL;
 
template <typename T> bool chkMax(T &x, T y) { return (y > x) ? x = y, 1 : 0; }
template <typename T> bool chkMin(T &x, T y) { return (y < x) ? x = y, 1 : 0; }
 
template <typename T> void inline read(T &x) {
    int f = 1; x = 0; char s = getchar();
    while (s < '0' || s > '9') { if (s == '-') f = -1; s = getchar(); }
    while (s <= '9' && s >= '0') x = x * 10 + (s ^ 48), s = getchar();
    x *= f;
}

const int N=1e5+5;
const LL inf=0x3f3f3f3f3f3f3f3f;
int n,k,a[N],q[N];
LL f[N],s;
int main()
{
    scanf("%d%d",&n,&k);
    int hh=0,tt=0;
    for(int i=1;i<=n;i++)
    {
    	scanf("%d",&f[i]);
    	s+=f[i];
    	while(hh<=tt&&i-1-q[hh]+1>k+1)hh++;
    	if(hh<=tt&&i>k-1)f[i]+=f[q[hh]];
    	while(hh<=tt&&f[q[tt]]>=f[i])tt--;
    	q[++tt]=i;
    }
    LL t=inf;
    if(n>=k+1)
    	for(int i=n-k;i<=n;i++)t=min(t,f[i]);
    if(t>inf/2)t=0;
    printf("%lld",s-t);
    return 0;
}

标签:1087,修剪,int,草坪,FJ,奶牛,define
From: https://www.cnblogs.com/zyyun/p/16961641.html

相关文章

  • 力扣 669. 修剪二叉搜索树
    669.修剪二叉搜索树给你二叉搜索树的根节点 root ,同时给定最小边界low 和最大边界 high。通过修剪二叉搜索树,使得所有节点的值在[low,high]中。修剪树 不应该......
  • LeetCode_669_修剪二叉搜索树
    题目描述:给定一个二叉搜索树,同时给定最小边界L和最大边界R。通过修剪二叉搜索树,使得所有节点的值在[L,R]中(R>=L)。你可能需要改变树的根节点,所以结果应当返回修剪好的......
  • 试题D修剪灌木
    以一个长为5的例子举例,这是爱丽丝修建的顺序,最高可以长到的高度等同于修剪的时间间隔最大i表示第i课数当i小于等于N/2时,它的修剪时间间隔最长是第一次修剪到第二次修......
  • 修剪草坪(mowlawn)
    题目描述在一年前赢得了小镇的最佳草坪比赛后,FJ变得很懒,再也没有修剪过草坪。现在,新一轮的最佳草坪比赛又开始了,FJ希望能够再次夺冠。然而,FJ的草坪非常脏乱,因此,FJ只能够......
  • leetcode 669. Trim a Binary Search Tree 修剪二叉搜索树 (简单)
    一、题目大意给你二叉搜索树的根节点root,同时给定最小边界low和最大边界high。通过修剪二叉搜索树,使得所有节点的值在[low,high]中。修剪树不应该改变保留在树中的......
  • 修剪草坪
    原题链接题目描述给定一个长度为n的数组a和一个整数m,a[i]表示i点的价值,从a中选择一些元素:不能选择连续m个元素使得总价值最大分析令f[i]表示以i为右端点的前缀区......
  • 1087 有多少不同的值——20分
    当自然数n依次取1、2、3、……、N时,算式⌊n/2⌋+⌊n/3⌋+⌊n/5⌋有多少个不同的值?(注:⌊x⌋为取整函数,表示不超过x的最大自然数,即x的整数部分。)输入格式:输入给......