简要题意

给你 \(N\) 本书 \((h_i,w_i)\),你要将书分成任意段(顺序不能改变),使得每一段 \(j\) 中 \(\sum\limits_{i \in j} w_i \leq L\),段 \(j\) 的代价为 \(\max\limits_{i \in j}{h_i}\)。你需要输出每一段的代价之和的最小值。

\(1 \leq N \leq 10^{5}\)

思路

朴素 DP 思路

设 \(f_i\) 为前 \(i\) 本书的代价和。则:

\[\begin{aligned}
& W(i,j) = \sum_{k=i}^{j}{w_k} \\
& H(i,j) = \max_{k=i}^{j}{h_k} \\
& f_i = \min_{W(j,i) \leq L}{(f_{j-1} + H(j,i))}
\end{aligned}
\]

解释:将 \([j,i]\) 中的书放在合并,然后成为一个新的段。

时间复杂度 \(O(n^3)\)。经过前缀和优化后 \(O(n^2)\),无法通过本题。

代码如下:

for(int i=1;i<=n;i++){
dp[i]=0x7f7f7f7f7fll;
sum[i]=sum[i-1]+w[i];
}
for(int i=1;i<=n;i++){
mn=INT_MIN;
for(int j=i;j>0;j--){
mn=max(mn,h[j]);
if(sum[i]-sum[j-1]<=m){
dp[i]=min(dp[i],dp[j-1]+mn);
}
else{
break;
}
}
}
cout<<dp[n];

喜提 \(69\operatorname{pts}\)

DP 优化

首先,最后一个满足 \(W(j,i) \leq l\) 的 \(j\) 是可以二分得出的(因为题目中 \(w\) 的前缀和是单调不降的)。我们姑且设其为 \(p_i\),则:

\[f_i = \min_{p_i}^{i}{(f_{j-1} + H(j,i))}
\]

另外我们设 \(l_i\) 为左边第一个满足 \(h_j>h_i\) 的 \(j\),即:

\[l_i = \max_{j=1}^{n}{(j \cdot [h_j > h_i])}
\]

那么如果 \(l_i \lt j \leq i\),则 \(H(j,i)=h_i\),只需要找到最小的 \(f_{j-1}\)即可。至于其他的,就用继承下来的。这是正确的。

这道题没法 ODT,老老实实的线段树。

代码

耗时最长的一道题祭

#include <bits/stdc++.h>
#define ls (i<<1)
#define rs (i<<1|1)
#define mid ((l+r)>>1)
#define int long long
using namespace std; int f,n,l,h[100005],w[100005],sumw[100005]; namespace sgt{
struct node{
int f,fh,tag;
} t[400005];
void pushup(int i){
t[i].f=min(t[ls].f,t[rs].f);
t[i].fh=min(t[ls].fh,t[rs].fh);
}
void pushdown(int i){
if(t[i].tag!=(-1e9)){
t[ls].fh=t[ls].f+t[i].tag;
t[rs].fh=t[rs].f+t[i].tag;
t[ls].tag=t[i].tag;
t[rs].tag=t[i].tag;
t[i].tag=(-1e9);
}
}
void build(int i,int l,int r){
if(l==r){
t[i].fh=LLONG_MAX;
t[i].f=t[i].fh;
t[i].tag=(-1e9);
return;
}
build(ls,l,mid);
build(rs,mid+1,r);
pushup(i);
}
void init(int p,int i,int l,int r){
if(l==r){
t[i].fh=LLONG_MAX;
t[i].f=f;
return;
}
pushdown(i);
if(p<=mid){
init(p,ls,l,mid);
}
else{
init(p,rs,mid+1,r);
}
pushup(i);
}
void assign(int ql,int qr,int k,int i,int l,int r){
if(ql<=l&&r<=qr){
t[i].fh=t[i].f+k;
t[i].tag=k;
return;
}
pushdown(i);
if(ql<=mid){
assign(ql,qr,k,ls,l,mid);
}
if(mid<qr){
assign(ql,qr,k,rs,mid+1,r);
}
pushup(i);
}
int get(int ql,int qr,int i,int l,int r){
if(ql<=l&&r<=qr){
return t[i].fh;
}
pushdown(i);
int ret=LLONG_MAX;
if(mid>=ql){
ret=min(ret,get(ql,qr,ls,l,mid));
}
if(mid<qr){
ret=min(ret,get(ql,qr,rs,mid+1,r));
}
return ret;
}
} stack<int> sta;
int lft[100005]; signed main(){
cin>>n>>l;
for(int i=1;i<=n;i++){
cin>>h[i]>>w[i];
sumw[i]=sumw[i-1]+w[i];
}
h[0]=INT_MAX;sta.push(0);
for(int i=1;i<=n;i++){
while(!sta.empty()&&h[i]>h[sta.top()]){
sta.pop();
}
lft[i]=sta.top();
sta.push(i);
}
sgt::build(1,1,n);
for(int i=1;i<=n;i++){
// cout<<"INIT "<<i<<'\n';
sgt::init(i,1,1,n);
// cout<<"ASSIGN "<<i<<'\n';
sgt::assign(lft[i]+1,i,h[i],1,1,n);
// cout<<"LOWERBOUND "<<i<<'\n';
int ll = lower_bound(sumw,sumw+i+1,sumw[i]-l)-sumw;
if(ll<i){
f=sgt::get(ll+1,i,1,1,n);
}
}
cout<<f;
}

P1848 [USACO12OPEN]Bookshelf G的更多相关文章

  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. p1848 [USACO12OPEN]书架Bookshelf

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

  3. 解题:USACO12OPEN Bookshelf

    题面 从零开始的DP学习之肆 当DP方程中的一部分具有某种单调性时可以用数据结构或者预处理维护来降低复杂度 一开始没有看懂题,尴尬,后来发现题目可以简化成这个样子: 将一个序列划分为若干段,每段长度不 ...

  4. pkuwc 前的任务计划

    菜鸡 wxw 的计划(肯定会咕咕咕 12.27 luogu P4244 [SHOI2008]仙人掌图 II(咕咕咕 luogu P4246 [SHOI2008]堵塞的交通 (没有咕! luogu P1 ...

  5. Storyboards Tutorial 03

    这一节主要介绍segues,static table view cells 和 Add Player screen 以及 a game picker screen. Introducing Segue ...

  6. 文件图标SVG

    ​<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink ...

  7. [USACO12OPEN]书架Bookshelf

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

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

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

  9. [转]Linux下g++编译与使用静态库(.a)和动态库(.os) (+修正与解释)

    在windows环境下,我们通常在IDE如VS的工程中开发C++项目,对于生成和使用静态库(*.lib)与动态库(*.dll)可能都已经比较熟悉,但是,在linux环境下,则是另一套模式,对应的静态库 ...

随机推荐

  1. 关于.Net 7.0 RC gRPC JSON 转码为 Swagger/OpenAPI文档的注意事项

    大家好,我是失业在家,正在找工作的博主Jerry,找工作之余,看到.Net 7.0 RC2发布了,就想测试下.Net 7.0 RC2 gRPC JSON 转码为 Swagger/OpenAPI文档的特 ...

  2. (数据科学学习手札145)在Python中利用yarl轻松操作url

    本文示例代码已上传至我的Github仓库https://github.com/CNFeffery/DataScienceStudyNotes 1 简介 大家好我是费老师,在诸如网络爬虫.web应用开发 ...

  3. C#接口设计

    基本架构 model 实体 说得通俗一些,model中主要是定义前端传过来的变量以及其类型,或者是需要操作的数据库中的某些字段值.举个例子: namespace Test.Models.Book { ...

  4. 论文笔记 - An Explanation of In-context Learning as Implicit Bayesian Inference

    这位更是重量级.这篇论文对于概率论学的一塌糊涂的我简直是灾难. 由于 prompt 的分布与预训练的分布不匹配(预训练的语料是自然语言,而 prompt 是由人为挑选的几个样本拼接而成,是不自然的自然 ...

  5. 云原生之旅 - 9)云原生时代网关的后起之秀Envoy Proxy 和基于Envoy 的 Emissary Ingress

    前言 前一篇文章讲述了基于Nginx代理的Kuberenetes Ingress Nginx[云原生时代的网关 Ingress Nginx]这次给大家介绍下基于Envoy的 Emissary Ingr ...

  6. 词向量word2vec(图学习参考资料)

    介绍词向量word2evc概念,及CBOW和Skip-gram的算法实现. 项目链接: https://aistudio.baidu.com/aistudio/projectdetail/500940 ...

  7. 图学习【参考资料2】-知识补充与node2vec代码注解

    本项目参考: https://aistudio.baidu.com/aistudio/projectdetail/5012408?contributionType=1 *一.正题篇:DeepWalk. ...

  8. Git+Github协作开发流程

    采用合作开发者的方式进行协作开发,下面以zlcook和zlserver合作开发iqas-ios-record项目为例进行讲解,zlcook为项目创建者,zlserver为项目参与者.协作开发步骤如下: ...

  9. 深度学习之logistics回归

    在开始之前,事先声明本文参考[中文][吴恩达课后编程作业]Course 1 - 神经网络和深度学习 - 第二周作业_何宽的博客-CSDN博客_吴恩达课后编程作业 加上自己的理解,希望可以不用重复看吴恩 ...

  10. fiddler提示"The system proxy was changed,click to reenable fiddler capture"的解决方法

    之前用fiddler 一直都是正常的,但是过了几个月再次使用的时候没几秒钟就提示:The system proxy was changed,click to reenable fiddler capt ...