http://www.lydsy.com/JudgeOnline/problem.php?id=2448

一遍过,嘎嘎嘎嘎嘎嘎嘎嘎嘎嘎嘎嘎,O(∩_∩)O~

题意是最小化最大值

设计区间dp

dp[i][j] 表示在能确定x不在区间[i,j]内,或确定x在区间[i,j]内某个位置的最坏情况下的最小值

dp[i][j]=min { max(dp[i][k-1],dp[k+1][j] ) + a[k] }  k∈[i,j]

O(n^3)复杂度

#include<cstdio>
#include<cstring>
#include<iostream> using namespace std; #define N 2002 int a[N]; int dp[N][N]; void read(int &x)
{
x=; char c=getchar();
while(!isdigit(c)) c=getchar();
while(isdigit(c)) { x=x*+c-''; c=getchar(); }
} int main()
{
int n;
read(n);
for(int i=;i<=n;++i) read(a[i]);
memset(dp,,sizeof(dp));
for(int i=;i<=n;++i)
dp[i][i]=a[i],dp[i][i-]=;
for(int i=n;i;--i)
for(int j=i;j<=n;++j)
for(int k=i;k<=j;++k)
dp[i][j]=min(dp[i][j],max(dp[i][k-],dp[k+][j])+a[k]);
printf("%d",dp[][n]);
}

优化:

把max去掉,就可以使用单调队列优化了

很显然的结论是长区间的dp值一定>=它的子区间的dp值

当固定i和j时,随着k的递增,dp[i][k-1]单调不降,dp[k+1][j]单调不增

所以一定可以找到一个分界点g,

当k∈[i,g]时,dp[i][k-1]>dp[k+1][j]

当k∈[g+1,j]时,dp[k+1][j]>dp[i][k-1]

所以上述转移方程变为

当k∈[i,g]时,dp[i][j]=min { dp[i][k-1]+a[k] }

当k∈[g+1,j]时,dp[i][j]=min { dp[k+1][j]+a[k] }

用g[i][j]表示对于每对i,j 求出的g

对于 当k∈[i,g[i][j] ]时,dp[i][j]=min { dp[i][k-1]+a[k] }

可以得出结论 g[a][b]<=g[a][b+1]

因为这里是前面的dp值>后面的dp值,[a,b+1]在[a,b]后面加了一个位置,

后面的dp值不变或增大,前面要包含更多的位置使前面变的更大,才能>=后面,所以g的位置不变或后移

所以固定区间左端点,随右端点的右移,g单调不减

对于 当k∈[g[i][j]+1,j]时,dp[i][j]=min { dp[k+1][j]+a[k] }

可以得出结论 g[a-1][b]<=g[a][b]

因为这里是后面的dp值>前面的dp值,[a-1,b]在[a,b]前面加了一个一个位置

前面的dp值不变或增大,后面要包含更多的位置使后面变的更大,才能>=前面,所以g的位置不变或前移

所以固定区间右端点,随左端点的左移,g单调不增

所以可维护n+1个单调队列

一个表示固定左端点,n个表示固定右端点

因为是左端点从n倒序枚举,右端点从左端点正序枚举

所以固定左端点的只需要用一个,左端点改变的时候清空队列即可

但是右端点是跳来跳去的,所以要用n个

实际实现的时候可以不计算g

如果要计算g的话,由上面可以得出结论

g[a-1][b]<=g[a][b]<=g[a][b+1]

利用g的单调性计算g

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm> using namespace std; #define N 2002 int a[N]; int dp[N][N]; int q[N][N];
int h[N],t[N]; #define A(x) dp[i][(x)-1]+a[(x)]
#define B(x) dp[(x)+1][j]+a[(x)] void read(int &x)
{
x=; char c=getchar();
while(!isdigit(c)) c=getchar();
while(isdigit(c)) { x=x*+c-''; c=getchar(); }
} int main()
{
int n;
read(n);
for(int i=;i<=n;++i) read(a[i]);
memset(dp,,sizeof(dp));
for(int i=n;i;--i)
{
dp[i][i]=a[i];
h[]=;
q[][t[]=]=i;
q[i][t[i]=]=i;
for(int j=i+;j<=n;++j)
{
while(h[]<t[] && A(q[][h[]])<B(q[][h[]])) ++h[];
while(h[]<t[] && A(j)<A(q[][t[]-])) --t[];
q[][t[]++]=j;
while(h[j]<t[j] && B(q[j][h[j]])<A(q[j][h[j]])) ++h[j];
while(h[j]<t[j] && B(i)<B(q[j][t[j]-])) --t[j];
q[j][t[j]++]=i;
dp[i][j]=min(A(q[][h[]]),B(q[j][h[j]]));
}
}
printf("%d",dp[][n]);
}

2448: 挖油

Time Limit: 10 Sec  Memory Limit: 128 MB
Submit: 133  Solved: 57
[Submit][Status][Discuss]

Description

给出一条线段,在左端点点0与右端点n+1间有n个点(n<=2000),并且在0到x之间的所有点都是有油的,在每个点钻井判断是否有油需要时间ti,求能够知道x的最坏情况下最少需要多少时间。
 

Input

第一行包含一个数n,如题目描述。
第二行包含n个数,表示在第i个点钻井判断是否有油需要的时间。
 

Output

输出包含一行,最坏情况下最少需要多少时间。
 

Sample Input

4
8 24 12 6

Sample Output

42

HINT

对于100%的数据,n<=2000,ti<=10^6

bzoj千题计划235:bzoj2448: 挖油的更多相关文章

  1. bzoj千题计划300:bzoj4823: [Cqoi2017]老C的方块

    http://www.lydsy.com/JudgeOnline/problem.php?id=4823 讨厌的形状就是四联通图 且左右各连一个方块 那么破坏所有满足条件的四联通就好了 按上图方式染色 ...

  2. bzoj千题计划196:bzoj4826: [Hnoi2017]影魔

    http://www.lydsy.com/JudgeOnline/problem.php?id=4826 吐槽一下bzoj这道题的排版是真丑... 我还是粘洛谷的题面吧... 提供p1的攻击力:i,j ...

  3. bzoj千题计划280:bzoj4592: [Shoi2015]脑洞治疗仪

    http://www.lydsy.com/JudgeOnline/problem.php?id=4592 注意操作1 先挖再补,就是补的范围可以包含挖的范围 SHOI2015 的题 略水啊(逃) #i ...

  4. bzoj千题计划177:bzoj1858: [Scoi2010]序列操作

    http://www.lydsy.com/JudgeOnline/problem.php?id=1858 2018 自己写的第1题,一遍过 ^_^ 元旦快乐 #include<cstdio> ...

  5. bzoj千题计划317:bzoj4650: [Noi2016]优秀的拆分(后缀数组+差分)

    https://www.lydsy.com/JudgeOnline/problem.php?id=4650 如果能够预处理出 suf[i] 以i结尾的形式为AA的子串个数 pre[i] 以i开头的形式 ...

  6. bzoj千题计划304:bzoj3676: [Apio2014]回文串(回文自动机)

    https://www.lydsy.com/JudgeOnline/problem.php?id=3676 回文自动机模板题 4年前的APIO如今竟沦为模板,,,╮(╯▽╰)╭,唉 #include& ...

  7. bzoj千题计划292:bzoj2244: [SDOI2011]拦截导弹

    http://www.lydsy.com/JudgeOnline/problem.php?id=2244 每枚导弹成功拦截的概率 = 包含它的最长上升子序列个数/最长上升子序列总个数 pre_len ...

  8. bzoj千题计划278:bzoj4590: [Shoi2015]自动刷题机

    http://www.lydsy.com/JudgeOnline/problem.php?id=4590 二分 这么道水题 没long long WA了两发,没判-1WA了一发,二分写错WA了一发 最 ...

  9. bzoj千题计划250:bzoj3670: [Noi2014]动物园

    http://www.lydsy.com/JudgeOnline/problem.php?id=3670 法一:KMP+st表 抽离nxt数组,构成一棵树 若nxt[i]=j,则i作为j的子节点 那么 ...

随机推荐

  1. vuex实践之路——笔记本应用(一)

    首先使用vue-cli把环境搭建好. 介绍一下应用的界面. App.vue根组件,就是整个应用的最外层 Toolbar.vue:最左边红色的区域,包括三个按钮,添加.收藏.删除. NoteList.v ...

  2. Redux系列01:从一个简单例子了解action、store、reducer

    其实,redux的核心概念就是store.action.reducer,从调用关系来看如下所示 store.dispatch(action) --> reducer(state, action) ...

  3. 算法(JAVA)----两道小小课后题

    LZ最近翻了翻JAVA版的数据结构与算法,无聊之下将书中的课后题一一给做了一遍,在此给出书中课后题的答案(非标准答案,是LZ的答案,猿友们可以贡献出自己更快的算法). 1.编写一个程序解决选择问题.令 ...

  4. StackGAN 阅读笔记

    StackGAN 阅读笔记 StackGAN论文下载链接(arxiv) 创新点 提出多尺度的GAN Stage-I GAN Stage-II GAN Stage-I GAN 主要是根据文本描述抓取目标 ...

  5. 科普贴 | 以太坊代币钱包MyEtherWallet使用教程,一步步教你玩转MEW

    MyEtherWallet 是一个以太坊的网页钱包,使用非常简单,打开网页就可以使用,源代码开源,不会在服务器上存储用户的钱包信息如私钥和密码.支持 Ledger Wallet.TREZOR 等硬件钱 ...

  6. Linux 第五章 学习笔记

    ---恢复内容开始--- 第五章 系统调用 一.与内核通信 1.系统调用在用户控件进程和硬件设备之间添加了一个中间层. 为用户空间提供了一种硬件的抽象接口 系统调用保证了系统的稳定和安全 每个进程都运 ...

  7. 冲刺Two之站立会议5

    昨天对视频音频的内容查询收集了相关资料,今天就主要对此进行了加工.先是使两台PC进行通信,不断进行测试.改进:测试.改进.最后初见成效,但还是没有达到我们最初的标准.

  8. 第一个spring,第五天。

    陈志棚:界面跳转与框架 李天麟:游戏界面ui 徐侃:算法代码的设计 经过五天的时间,经过队员的汇报,我们初步已经完成了各项的任务.

  9. 团队冲刺随笔合集—Beta阶段

    第一篇:http://www.cnblogs.com/Team-Blog/p/9049271.html 第二篇:https://www.cnblogs.com/Team-Blog/p/9064478. ...

  10. VS社区版 使用 OpenCover 获取测试代码覆盖率

    注:暂不支持VS2017 Visual Studio 2015 社区版没有集成代码覆盖率的功能,所以想在VS社区版中获取单元测试的代码覆盖率等数据,需要使用到插件 OpenCover. 下载 Open ...