题面

从零开始的DP学习之肆

当DP方程中的一部分具有某种单调性时可以用数据结构或者预处理维护来降低复杂度

一开始没有看懂题,尴尬,后来发现题目可以简化成这个样子: 将一个序列划分为若干段,每段长度不超过$L$,求每段中最大值之和的最小值

看起来可以直接二分,然而大概并不可行,不过我们有一个明显的$O(n^2)$的DP思路,和我最近做的一道题思路一样。设$dp[i]$表示以$i$为结尾的最小花费,枚举结尾$i$,在$1->i$中找到所有与$i$间距不超过$L$的$j$来转移,代价就是$(j,i)$中的最大值,可以ST表预处理。即$dp[i]=min(dp[i],dp[j]+max(j,i))(j<=i\&\&\sum\limits_{k=j}^i width[k]<=L)$

考虑如何优化,发现$dp$数组在顺序下是单调不下降的,而当右端点$i$确定时,所有的$j$的最大值在顺序下是单调不上升的,所以我们可以考虑用线段树维护这个最小花费,也就是维护$dp[j]+max(j,i)$的最小值。我们枚举右端点时候相当于移动一个长度不超过$L$的滑动窗口,然后我们对于每个新加入的高度就维护一下它左边这段的最大高度,求出$dp[i]$后再单点修改一下下一个位置就可以了

具体来说是用线段树维护四个值+一个标记:最小值,最大值,dp数组,最小花费。其中最小值是为了在维护最大值的时候二分用的,当找到一个要修改的区间的时候我们二分出要修改的那一块,具体来说就是这块中的最小值小于我们要修改成的值再进去修改。然后说说这只蒟蒻都WA了什么鬼畜的错误,第一次是pushup用串了(雾);第二次是因为调试的时候写的和平时不太一样了,然后线段树release了叶子节点=。=;最后一次发现是区间没卡准(之前都是怎么过的2333)

 #include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=;
long long dp[*N],mini[*N],maxx[*N];
long long laz[*N],val[*N];
long long w[N],h[N];
long long n,m,f,tot,ans;
void pushup(int nde)
{
int ls=*nde,rs=*nde+;
maxx[nde]=max(maxx[ls],maxx[rs]);
mini[nde]=min(mini[ls],mini[rs]);
val[nde]=min(val[ls],val[rs]);
}
void release(int nde)
{
if(laz[nde])
{
int ls=*nde,rs=*nde+;
laz[ls]=mini[ls]=maxx[ls]=laz[nde];
laz[rs]=mini[rs]=maxx[rs]=laz[nde];
val[ls]=dp[ls]+maxx[ls],val[rs]=dp[rs]+maxx[rs]; laz[nde]=;
}
}
void change1(int nde,int l,int r,int nl,int nr,long long task)
{
if(l>nr||r<nl) return ;
if(l!=r) release(nde); int mid=(l+r)/,ls=*nde,rs=*nde+;
if(l>=nl&&r<=nr)
{
if(task<=maxx[nde])
{
if(task>mini[ls]) change1(ls,l,mid,nl,nr,task);
if(task>mini[rs]) change1(rs,mid+,r,nl,nr,task);
}
else
{
maxx[nde]=mini[nde]=laz[nde]=task;
val[nde]=dp[nde]+maxx[nde]; return ;
}
}
else
change1(ls,l,mid,nl,nr,task),change1(rs,mid+,r,nl,nr,task);
pushup(nde);
}
void change2(int nde,int l,int r,int pos,long long task)
{
if(l==pos&&r==pos) {dp[nde]=task; return ;}
release(nde); int mid=(l+r)/,ls=*nde,rs=*nde+;
if(pos<=mid) change2(ls,l,mid,pos,task);
else change2(rs,mid+,r,pos,task);
dp[nde]=min(dp[ls],dp[rs]);
}
long long query(int nde,int l,int r,int nl,int nr)
{
if(l>nr||r<nl)
return 1e18;
else if(l>=nl&&r<=nr)
return val[nde];
else
{
int mid=(l+r)/,ls=*nde,rs=*nde+; release(nde);
return min(query(ls,l,mid,nl,nr),query(rs,mid+,r,nl,nr));
}
}
int main ()
{
scanf("%lld%lld",&n,&m),f=;
for(int i=;i<=n;i++)
scanf("%lld%lld",&h[i],&w[i]);
for(int i=;i<=n;i++)
{
tot+=w[i];
while(tot>m) tot-=w[f++];
change1(,,n,,i,h[i]);
ans=query(,,n,f,i);
if(i!=n) change2(,,n,i+,ans);
}
printf("%lld",ans);
return ;
}

解题:USACO12OPEN Bookshelf的更多相关文章

  1. 2021.12.08 P1848 [USACO12OPEN]Bookshelf G(线段树优化DP)

    2021.12.08 P1848 [USACO12OPEN]Bookshelf G(线段树优化DP) https://www.luogu.com.cn/problem/P1848 题意: 当农夫约翰闲 ...

  2. [USACO12OPEN]书架Bookshelf

    Description 当农夫约翰闲的没事干的时候,他喜欢坐下来看书.多年过去,他已经收集了 N 本书 (1 <= N <= 100,000), 他想造一个新的书架来装所有书. 每本书 i ...

  3. [Luogu1848][USACO12OPEN]书架Bookshelf DP+set+决策单调性

    题目链接:https://www.luogu.org/problem/show?pid=1848 题目要求书必须按顺序放,其实就是要求是连续的一段.于是就有DP方程$$f[i]=min\{f[j]+m ...

  4. p1848 [USACO12OPEN]书架Bookshelf

    分析 单调队列优化dp即可 正确性显然,详见代码 代码 #include<bits/stdc++.h> using namespace std; #define int long long ...

  5. POJ 3268 Bookshelf 2 动态规划法题解

    Description Farmer John recently bought another bookshelf for the cow library, but the shelf is gett ...

  6. SCNU ACM 2016新生赛决赛 解题报告

    新生初赛题目.解题思路.参考代码一览 A. 拒绝虐狗 Problem Description CZJ 去排队打饭的时候看到前面有几对情侣秀恩爱,作为单身狗的 CZJ 表示很难受. 现在给出一个字符串代 ...

  7. SCNU ACM 2016新生赛初赛 解题报告

    新生初赛题目.解题思路.参考代码一览 1001. 无聊的日常 Problem Description 两位小朋友小A和小B无聊时玩了个游戏,在限定时间内说出一排数字,那边说出的数大就赢,你的工作是帮他 ...

  8. HDU 3791二叉搜索树解题(解题报告)

    1.题目地址: http://acm.hdu.edu.cn/showproblem.php?pid=3791 2.参考解题 http://blog.csdn.net/u013447865/articl ...

  9. 【BZOJ1700】[Usaco2007 Jan]Problem Solving 解题 动态规划

    [BZOJ1700][Usaco2007 Jan]Problem Solving 解题 Description 过去的日子里,农夫John的牛没有任何题目. 可是现在他们有题目,有很多的题目. 精确地 ...

随机推荐

  1. 深度学习之神经网络核心原理与算法-caffe&keras框架图片分类

    之前我们在使用cnn做图片分类的时候使用了CIFAR-10数据集 其他框架对于CIFAR-10的图片分类是怎么做的 来与TensorFlow做对比. Caffe Keras 安装 官方安装文档: ht ...

  2. 第二次作业(homework-02)成绩公布

    学位后三位和对应成绩: 057 0008 4011 4012 7014 5015 5017 6018 0019 0026 2027 7036 0038 7.5046 7048 6.5051 0061 ...

  3. LeetCode 461. Hamming Distance (C++)

    题目: The Hamming distance between two integers is the number of positions at which the corresponding ...

  4. Beta冲刺第二周王者荣耀交流协会第五次会议

    1.立会照片 成员:王超,高远博,冉华,王磊,王玉玲,任思佳,袁玥全部到齐. master:王磊 2.时间跨度: 2017年11月21日 15:00 — 15:17,总计17分钟. 3.地点: 一食堂 ...

  5. 软件工程-东北师大站-第八次作业(PSP)

    1.本周PSP 2.本周进度条 3.本周累计进度图 代码累计折线图 博文字数累计折线图 4.本周PSP饼状图

  6. js格式化json字符串和json对象

    1,格式化json对象 var json = {"@odata.context":"$metadata#AddTableOne_466281s","v ...

  7. 20135231 JAVA实验报告三:敏捷开发与XP实践

    ---恢复内容开始--- JAVA实验报告三:敏捷开发与XP实践 20135231 何佳 实验内容 1. XP基础 2. XP核心实践 3. 相关工具 实验要求 1.没有Linux基础的同学建议先学习 ...

  8. 冲刺One之站立会议5 /2015-5-18

    2015-5-18 服务器部分大体已经完工,现在我们主要是在把登陆界面和服务器组装起来,这个过程是很让人头痛的,以为其中涉及到了很多网络协议.网络编程的知识,由于之前我们没有接触过所以实现起来会觉得很 ...

  9. Reaction to 构造之法 of Software Engineering From The First Chapter toThe Fifth Chapter(补充版)

    几个星期前,我阅读过一篇文章,一位老师教导自己的学生要积极地去阅读文学文献,其中,我很欣赏他的一句话:“Just think of liturature as if you're reading a ...

  10. ACM的fflush(stdin)的问题

    在最近的刷题过程中,因为用到了很多字符串的操作,有时需要多次清空缓冲区,所以用了fflush(stdin);的语句,确实很好用,但是发现在OJ上提交后会出现runtime error的问题.当时并没有 ...