[题目链接]

https://www.lydsy.com/JudgeOnline/problem.php?id=2678

[算法]

首先不难想到如下DP :

记f[i]表示前i本书的高度和最小值

显然 , 有状态转移方程 : f[i] = min{ fj + max{hj+1 , hj+2 , ... hi} }

不难发现 , 当i确定时 , 随着j的减小 , max{hj + 1 , hj+2 , ... hi}的值单调递增

不妨维护一个单调递减的单调栈

预处理前缀和 , 每次在单调栈中二分出最靠左的左端点

然后 , 我们还需维护一棵支持单点修改 , 区间查询的线段树

每次在线段树中找到从合法左端点到当前点的最小值

详见代码 , 时间复杂度 : O(NlogN)

#include<bits/stdc++.h>
using namespace std;
#define MAXN 100010
typedef long long LL;
const LL inf = 1e18; struct info
{
LL h , w;
} a[MAXN]; LL n , top;
LL L;
int s[MAXN];
LL cnt[MAXN] , dp[MAXN]; struct Segment_Tree
{
struct Node
{
int l , r;
LL mn;
} Tree[MAXN << ];
inline void build(int index , int l , int r)
{
Tree[index] = (Node){l , r , inf};
if (l == r) return;
int mid = (l + r) >> ;
build(index << , l , mid);
build(index << | , mid + , r);
}
inline void update(int index)
{
Tree[index].mn = min(Tree[index << ].mn , Tree[index << | ].mn);
}
inline void modify(int index , int pos , LL value)
{
if (Tree[index].l == Tree[index].r)
{
Tree[index].mn = value;
return;
}
int mid = (Tree[index].l + Tree[index].r) >> ;
if (mid >= pos) modify(index << , pos , value);
else modify(index << | , pos , value);
update(index);
}
inline LL query(int index , int l , int r)
{
if (l > r) return inf;
if (Tree[index].l == l && Tree[index].r == r) return Tree[index].mn;
int mid = (Tree[index].l + Tree[index].r) >> ;
if (mid >= r) return query(index << , l , r);
else if (mid + <= l) return query(index << | , l , r);
else return min(query(index << , l , mid) , query(index << | , mid + , r));
}
} SGT; template <typename T> inline void chkmax(T &x , T y) { x = max(x , y); }
template <typename T> inline void chkmin(T &x , T y) { x = min(x , y); }
template <typename T> inline void read(T &x)
{
T f = ; x = ;
char c = getchar();
for (; !isdigit(c); c = getchar()) if (c == '-') f = -f;
for (; isdigit(c); c = getchar()) x = (x << ) + (x << ) + c - '';
x *= f;
} int main()
{ read(n); read(L);
for (int i = ; i <= n; i++)
{
read(a[i].h);
read(a[i].w);
cnt[i] = cnt[i - ] + a[i].w;
}
SGT.build( , , n + );
s[top = ] = ;
dp[] = s[] = ;
SGT.modify( , , );
for (int i = ; i <= n; i++)
{
while (top > && a[i].h > a[s[top]].h) --top;
s[++top] = i;
SGT.modify( , top , dp[s[top - ]] + a[i].h);
int l = , r = top , pos = ;
while (l <= r)
{
int mid = (l + r) >> ;
if (cnt[i] - cnt[s[mid]] <= L)
{
pos = mid;
r = mid - ;
} else l = mid + ;
}
int loc = lower_bound(cnt , cnt + n + , cnt[i] - L) - cnt;
dp[i] = SGT.query( , pos + , top);
chkmin(dp[i] , dp[loc] + a[s[pos]].h);
}
cout<< dp[n] << '\n'; return ;
}

[USACO2012 OPEN] Bookshelf的更多相关文章

  1. [BZOJ2678][Usaco2012 Open]Bookshelf

    P.S. 偶然间发现可以用 markdown... [BZOJ2678][Usaco2012 Open]Bookshelf 试题描述 When Farmer John isn't milking co ...

  2. bzoj AC倒序

    Search GO 说明:输入题号直接进入相应题目,如需搜索含数字的题目,请在关键词前加单引号 Problem ID Title Source AC Submit Y 1000 A+B Problem ...

  3. bookshelf

    nodejs mysql ORM 比node-mysql好用多了. bookshelf 支持restful功能,用到的时候研究下:https://www.sitepoint.com/getting-s ...

  4. POJ3628 Bookshelf 2(01背包+dfs)

    Bookshelf 2 Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 8745   Accepted: 3974 Descr ...

  5. Bookshelf 2

    Bookshelf 2 Time Limit:1000MS     Memory Limit:65536KB     64bit IO Format:%I64d & %I64u Submit  ...

  6. POJ 3628 Bookshelf 2(01背包)

    Bookshelf 2 Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 9488   Accepted: 4311 Descr ...

  7. 动态规划(状态压缩):BZOJ 2621 [Usaco2012 Mar]Cows in a Skyscraper

      2621: [Usaco2012 Mar]Cows in a Skyscraper Time Limit: 20 Sec  Memory Limit: 128 MBSubmit: 303  Sol ...

  8. BZOJ3016: [Usaco2012 Nov]Clumsy Cows

    3016: [Usaco2012 Nov]Clumsy Cows Time Limit: 1 Sec  Memory Limit: 128 MBSubmit: 71  Solved: 52[Submi ...

  9. BZOJ 3011: [Usaco2012 Dec]Running Away From the Barn( dfs序 + 主席树 )

    子树操作, dfs序即可.然后计算<=L就直接在可持久化线段树上查询 -------------------------------------------------------------- ...

随机推荐

  1. POJ 1991 Turning in Homework(区间DP)

    题目链接 Turning in Homework 考虑区间DP $f[i][j][0]$为只考虑区间$[i, j]$且最后在$a[i]$位置交作业的答案. $f[i][j][1]$为只考虑区间$[i, ...

  2. delphi函数大全

    delphi函数大全Abort                 函数    引起放弃的意外处理Abs                   函数    绝对值函数AddExitProc          ...

  3. 【Java TCP/IP Socket】TCP Socket(含代码)

    TCP的Java支持 协议相当于相互通信的程序间达成的一种约定,它规定了分组报文的结构.交换方式.包含的意义以及怎样对报文所包含的信息进行解析,TCP/IP协议族有IP协议.TCP协议和UDP协议.现 ...

  4. Vue.js组件的通信之子组件向父组件的通信

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  5. centos安装python的虚拟环境和虚拟管理环境

    一.大部分介绍的方式是使用pip安装:1.pip install virtualenv     2.pip install virtualenvwrapper 但是我安装完,并没有相应的命令:virt ...

  6. Effective C++ 条款八 别让异常逃离析构函数

    class DBConn //这个class用来管理DBConnction对象 { public:   //自己设计一个新的DBConn接口 方法3 void close() { db.close() ...

  7. MapReduce将HDFS文本数据导入HBase中

    HBase本身提供了很多种数据导入的方式,通常有两种常用方式: 使用HBase提供的TableOutputFormat,原理是通过一个Mapreduce作业将数据导入HBase 另一种方式就是使用HB ...

  8. TinyXML:属性

    TiXmlAttribute: 代表XML中的属性,TiXmlAttribute中定义了一系列对属性的操作 TiXmlAttribute的友元类: friend class TiXmlAttribut ...

  9. region split流程分析

    region split流程分析 splitregion的发起主要通过client端调用regionserver.splitRegion或memstore.flsuh时检查并发起. Client通过r ...

  10. hdu4921 Map

    给最多10条链.每条链长度最大1000,链上每点有权值,每条链上按顺序,第i个点属于level[i]. 链上后一个点能够选的前提是前面的点都选了. 选择了一些点能够得到的分数是两部分加起来:1.所有点 ...