zoukankan      html  css  js  c++  java
  • 修剪草坪

    https://loj.ac/problem/10177

    题目描述

      每个奶牛有一定效率,不能安排编号连续超过(k)头奶牛,求最大效率。

    思路

      比较容易设计出(dp)的状态,我们用(f[i][0/1])表示前(i)头奶牛第(i)头奶牛选/不选获得的最大效率。那么(f[i][0]=max{f[i-1][0],f[i-1][1]}),而(f[i][1]=max{sum_{k=j}^{i}f[k][1]}+a[i](i-m+1le jle i-1)),表示从(j)开始选连续的一段以(i)为右端点的区间的最大值,为了能去掉内层循环,我们可以用前缀和以及单调队列优化掉,这样复杂度为(O(N))

    代码

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    
    ll read()
    {
    	ll res=0,w=1;
    	char ch=getchar();
    	while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();}
    	while(ch>='0'&&ch<='9'){res=(res<<3)+(res<<1)+(ch^48);ch=getchar();}
    	return res*w;
    }
    void write(ll x)
    {
    	if(x>9)write(x/10);
    	putchar(x%10+'0');
    }
    
    ll f[100010][2],sum[100010],q[100010],pos[100010];
    int main()
    {
    	int n=read(),k=read(),x;
    	for(int i=1;i<=n;i++)
    		x=read(),sum[i]=sum[i-1]+x;
    	int head=1,tail=1;
    	for(int i=1;i<=n;i++)
    	{
    		f[i][0]=max(f[i-1][0],f[i-1][1]);
    		while(head<=tail&&pos[head]<i-k)head++;
    		f[i][1]=f[pos[head]][0]-sum[pos[head]]+sum[i];
    		while(head<=tail&&f[pos[tail]][0]-q[tail]<=f[i][0]-sum[i])tail--;
    		q[++tail]=sum[i];pos[tail]=i;
    	}
    	write(max(f[n][0],f[n][1]));
    }
    
  • 相关阅读:
    01_3_创建一个Action
    01_2_Namespace命名空间
    01_1_Socket实现
    03_2_JAVA中的面向对象与内存解析
    01_1_Struts环境搭建
    Zabbix通过Orabbix监控Oracle数据库
    Zabbix通过JMX方式监控java中间件
    nginx启用status状态页
    zabbix数据库分表的实现
    配置sudo记录日志
  • 原文地址:https://www.cnblogs.com/fangbozhen/p/11851701.html
Copyright © 2011-2022 走看看