BZOJ 2442 [Usaco2011 Open]修剪草坪:单调队列优化dp
题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=2442
题意:
有n个数a[i]从左到右排成一排。
你可以任意选数,但是连续的数不能超过k个。
问你最大的选数之和。
题解:
表示状态:
dp[i]表示考虑了第i个数的最大之和。
找出答案:
ans = dp[n]
将所有的数都考虑过了
如何转移:
对于a[i],要么选,要么不选。
(1)如果不选,则dp[i] = max dp[i-1]。
(2)如果选,则最多往前选k个数,且在i-k的位置一定不能选。
所以:
dp[i] = max dp[j] + sum(j+2,i) (i-k-1 <= j <= i-2)
变成前缀和的形式:
dp[i] = max dp[j] + sum[i] - sum[j+1]
也就是:
dp[i] = max(dp[j] - sum[j+1]) + sum[i]
对于dp[j] - sum[j+1]这一部分,可以用单调队列优化。
边界条件:
dp[0] = 0
q[head++] = Node(-1,0)
-1为假想的位置,只是为了在n == 1的时候能够用到0这个值。
AC Code:
// state expression:
// dp[i] = max efficiency
// i: selected ith cow
//
// find the answer:
// max dp[n]
//
// transferring:
// dp[i] = max(dp[j] + sum(j+2,i), dp[i-1])
// dp[i] = max(dp[j] + sum[i] - sum[j+1], dp[i-1])
// dp[i] = max(dp[j] - sum[j+1] + sum[i], dp[i-1])
// i-k-1 <= j <= i-2
//
// boundary:
// dp[0] = 0
#include <iostream>
#include <stdio.h>
#include <string.h>
#define MAX_N 100005 using namespace std; struct Node
{
int idx;
long long val;
Node(int _idx,long long _val)
{
idx=_idx;
val=_val;
}
Node(){}
}; int n,k;
int head=;
int tail=;
int e[MAX_N];
long long dp[MAX_N];
long long sum[MAX_N];
Node q[MAX_N]; void read()
{
cin>>n>>k;
sum[]=;
for(int i=;i<=n;i++)
{
cin>>e[i];
sum[i]=sum[i-]+e[i];
}
} void solve()
{
dp[]=;
q[tail++]=Node(-,);
for(int i=;i<=n;i++)
{
if(i>=)
{
while(head<tail && q[tail-].val<dp[i-]-sum[i-]) tail--;
q[tail++]=Node(i-,dp[i-]-sum[i-]);
}
while(head<tail && q[head].idx<i-k-) head++;
dp[i]=max(q[head].val+sum[i],dp[i-]);
}
} void print()
{
cout<<dp[n]<<endl;
} int main()
{
read();
solve();
print();
}
BZOJ 2442 [Usaco2011 Open]修剪草坪:单调队列优化dp的更多相关文章
- bzoj2442[Usaco2011 Open]修剪草坪 单调队列优化dp
2442: [Usaco2011 Open]修剪草坪 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 1159 Solved: 593[Submit] ...
- BZOJ 2442: [Usaco2011 Open]修剪草坪 单调队列
Code: #include<iostream> #include<cstdio> #include<cstring> #include<algorithm& ...
- 修剪草坪 单调队列优化dp BZOJ2442
题目描述 在一年前赢得了小镇的最佳草坪比赛后,Farm John变得很懒,再也没有修剪过草坪.现在,新一轮的最佳草坪比赛又开始了,Farm John希望能够再次夺冠. 然而,Farm John的草坪非 ...
- P2627 修剪草坪 (单调队列优化$dp$)
题目链接 Solution 70分很简单的DP,复杂度 O(NK). 方程如下: \[f[i][1]=max(f[j][0]+sum[i]-sum[j])\]\[f[i][0]=max(f[i-1][ ...
- bzoj2442[Usaco2011 Open]修剪草坪——单调队列优化
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2442 考虑记录前 i 个.末尾 j 个连续选上的最大值.发现时空会爆. 又发现大量的转移形如 ...
- BZOJ 2442: [Usaco2011 Open]修剪草坪( dp )
dp dp[ i ] 表示第 i 个不选 , 前 i 个的选择合法的最小损失 , dp[ i ] = min( dp[ j ] ) ( max( 0 , i - 1 - k ) <= j < ...
- ●BZOJ 2442 [Usaco2011 Open]修剪草坪
题链: http://www.lydsy.com/JudgeOnline/problem.php?id=2442 题解: 单调队列优化DP 把问题转化为:从序列里选出一些相邻之间间隔不超过K的数,使得 ...
- BZOJ 2806 [Ctsc2012]Cheat ——后缀自动机 单调队列优化DP
先建出广义后缀自动机. 然后跑出文章中每一个位置的最大匹配距离. 然后定义$f[i]$表示匹配到以$i$结尾的串时,最长的匹配距离. 显然可以二分$L$的取值. 然后容易得到$DP$方程 $f[i]= ...
- BZOJ 2442: [Usaco2011 Open]修剪草坪
Description 在一年前赢得了小镇的最佳草坪比赛后,FJ变得很懒,再也没有修剪过草坪.现在,新一轮的最佳草坪比赛又开始了,FJ希望能够再次夺冠.然而,FJ的草坪非常脏乱,因此,FJ只能够让他的 ...
随机推荐
- mongodb分片片键的选择(持续更新中)
首先要了解项目的情况,检查使用情况 对集合进行分片时,要选择一个或者两个字段拆分数据,这个键叫做片键 一旦拥有对个分片,在修改片键几乎是不肯能的事情,因此选择合适的片键是非常重要的. 对集合分片之前要 ...
- 学习已经被淘汰的flash
一.基本知识介绍 网站动画的分类:二维动画和三维动画 二维动画分类: 1.GIF动画 2.flash动画 flash软件:是矢量软件 选中带有点,并且可以任意变形的对象,叫形状 逐帧动画:在时 ...
- MSComm串口类的使用 (程序设计)
参考文档:http://wenku.baidu.com/link?url=MLGQojaxyHnEgngEAXG8oPnISuM9SVaDzNTvg0oTSrrJkMXIR_6MR3cO_Vnh-gr ...
- bottle的几个小坑
距离我在<web.py应用工具库:webpyext>里说要换用bottle,已经过去快两个月了--事实上在那之前我已经開始着手在换了.眼下那个用于 Backbone.js 介绍的样例程序已 ...
- ARM和STM32的区别及ARM公司架构的发展
ARM和STM32的区别及ARM公司架构的发展 转:https://www.cnblogs.com/kwdeblog/p/5260348.html ARM是英国的芯片设计公司,其最成功的莫过于32位嵌 ...
- LeetCode 之 Valid Palindrome(字符串)
[问题描写叙述] Given a string, determine if it is a palindrome, considering only alphanumeric characters a ...
- EntityFramework 6.0 修改一个已经存在的对象
public void UpdateObj(someobject obj) { db.Entry(obj).State = EntityState.Modified; db.SaveChanges() ...
- wifi认证Portal开发系列(一):Radius与FreeRadius简介
RADIUS 维基百科上的介绍: Remote Authentication Dial-In User Service (RADIUS) is a networking protocol that p ...
- java中url正则regex匹配
String regex = "^(?:https?://)?[\\w]{1,}(?:\\.?[\\w]{1,})+[\\w-_/?&=#%:]*$"; 解释说明: ^ : ...
- oracle 误删数据的回复操作
update operator t set t.username = (select username from operator AS OF TIMESTAMP TO_TIMESTAMP('201 ...