【NOIP2016提高A组集训第12场11.10】灵知的太阳信仰
(File IO): input:array.in output:array.out
Time Limits: 1000 ms Memory Limits: 131072 KB Detailed Limits

Description

在炽热的核熔炉中,居住着一位少女,名为灵乌路空。
据说,从来没有人敢踏入过那个熔炉,因为人们畏缩于空所持有的力量——核能。
核焰,可融真金。

咳咳。
每次核融的时候,空都会选取一些原子,排成一列。然后,她会将原子序列分成一些段,并将每段进行一次核融。
一个原子有两个属性:质子数和中子数。
每一段需要满足以下条件:
1、同种元素会发生相互排斥,因此,同一段中不能存在两个质子数相同的原子。
2、核融时,空需要对一段原子加以防护,防护罩的数值等于这段中最大的中子数。换句话说,如果这段原子的中子数最大为x,那么空需要付出x的代价建立防护罩。求核融整个原子序列的最小代价和。

Input

第一行一个正整数N,表示原子的个数。
接下来N行,每行两个正整数pi和ni,表示第i个原子的质子数和中子数。

Output

输出一行一个整数,表示最小代价和。

Sample Input

5
3 11
2 13
1 12
2 9
3 13

Sample Output

26

Data Constraint

对于20%的数据,1<=n<=100
对于40%的数据,1<=n<=1000
对于100%的数据,1&lt;=n&lt;=105,1&lt;=pi&lt;=n,1&lt;=ni&lt;=2∗1041&lt;=n&lt;=10^5,1&lt;=pi&lt;=n,1&lt;=ni&lt;=2*10^41<=n<=105,1<=pi<=n,1<=ni<=2∗104


先放一波官方题解:


考场上其实连最简单的那个dp都没有想到,想的二维的状态,时间和空间都是n2n^2n2的,后来发现其实有一维无用状态。
然后最简单的那个n2n^2n2dp非常好理解对吧。
但是这样的转移时间复杂度非常高。(虽然我还码了一遍)

//
#include<queue>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
#define N 100005
#define INF 0x3f3f3f3f
#define ll long long
struct node{int a,b;
}at[N];
int n;
int last[N]/*这个点最左可以到哪里*/,pos[N]/*对应编号上一次出现的位置*/,dp[N];
inline int rd()
{int f=1,x=0;char c=getchar();while(c<'0'||'9'<c){if(c=='-')f=-1;c=getchar();}while('0'<=c&&c<='9') x=(x<<3)+(x<<1)+(c^48),c=getchar();return f*x;
}
int main()
{freopen("array.in","r",stdin);freopen("array.out","w",stdout);n=rd();for(register int i=1;i<=n;i++){scanf("%d %d",&at[i].a,&at[i].b);last[i]=last[i-1];if(pos[at[i].a]) last[i]=max(last[i],pos[at[i].a]+1);pos[at[i].a]=i;}for(register int i=1;i<=n;i++){int mx=at[i].b;dp[i]=dp[i-1]+at[i].b;for(register int j=i-1;j>=last[i];j--){mx=max(mx,at[j].b);dp[i]=min(dp[i],dp[j-1]+mx);}}printf("%d\n",dp[n]);return 0;
}

然后发现转移后面那一坨dp[j−1]+mxdp[j-1]+mxdp[j−1]+mx的复杂度非常高,想到单调队列优化。
发现当右端点i固定左端点j向左扫时其间b的最大值mx是不减的
这就相当于在找到下一个更大值之前mx不会变
这里维护一个递减的单调队列表示从i向左扫到那些位置会使mx发生变化
由于dp是单调不减的,在mx不变时用最左边的dp一定是最小值
这就相当于在单调队列中的每一项的f加上下一位的mx

然后就可以单调队列优化一下。
但是看题解的意思,好像暴力(正常)维护单调队列会造成没有必要的入队,所以还要用其他数据结构维护?
蒟蒻没有看懂,不会写,所以写了一个正常(暴力)的单调队列,过了,541ms,虽然跑得不快,但是看起来也不像是卡过去的,所以就这样吧。。。

//单调队列优化dp
#include<queue>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
#define N 100005
#define INF 0x3f3f3f3f
#define ll long long
inline int rd()
{int f=1,x=0;char c=getchar();while(c<'0'||'9'<c){if(c=='-')f=-1;c=getchar();}while('0'<=c&&c<='9') x=(x<<3)+(x<<1)+(c^48),c=getchar();return f*x;
}
int n;
int Q[N],head,tail;
int a[N],b[N],dp[N],pos[N],last[N];
int main()
{freopen("array.in","r",stdin);freopen("array.out","w",stdout);n=rd();for(int i=1;i<=n;i++){a[i]=rd(),b[i]=rd();if(!pos[a[i]])pos[a[i]]=i,last[i]=0;else last[i]=pos[a[i]],pos[a[i]]=i;last[i]=max(last[i],last[i-1]);//不能越过上一个数不能到达的位置 }head=tail=1;Q[tail]=1;dp[1]=b[1];for(int i=2;i<=n;i++){while(head<=tail&&last[i]>Q[head])head++;while(head<=tail&&b[Q[tail]]<=b[i])tail--;Q[++tail]=i;//先更新 可以从自己更新 dp[i]=INF;for(int j=head+1;j<=tail;j++)dp[i]=min(dp[i],dp[Q[j-1]]+b[Q[j]]);dp[i]=min(dp[i],dp[last[i]]+b[Q[head]]);//单独处理队头 }printf("%d\n",dp[n]);return 0;
}

【单调队列优化dp】jzoj4883灵知的太阳信仰 纪中集训提高B组相关推荐

  1. 算法笔记--单调队列优化dp

    单调队列:队列中元素单调递增或递减,可以用双端队列实现(deque),队列的前面和后面都可以入队出队. 单调队列优化dp: 问题引入: dp[i] = min( a[j] ) ,i-m < j ...

  2. poj 2373(单调队列优化dp)

    在长为L(<=1000000)的草地(可看成线段)上装喷水头,喷射是以这个喷水头为中心,喷水头的喷洒半径是可调节的调节范围为[a,b].要求草地的每个点被且只被一个喷水头覆盖,并且有些连续区间必 ...

  3. poj 1821(单调队列优化dp)

    题意:有一道线性篱笆由N个连续的木板组成.有K个工人,你要叫他们给木板涂色.每个工人有3个参数:L 表示 这个工人可以涂的最大木板数目,S表示这个工人站在哪一块木板,P表示这个工人每涂一个木板可以得到 ...

  4. 洛谷P3195 [HNOI2008]玩具装箱TOY(单调队列优化DP)

    题目描述 P教授要去看奥运,但是他舍不下他的玩具,于是他决定把所有的玩具运到北京.他使用自己的压缩器进行压缩,其可以将任意物品变成一堆,再放到一种特殊的一维容器中.P教授有编号为1...N的N件玩具, ...

  5. 【计蒜客 - 蓝桥训练】蒜厂年会(单调队列优化dp,循环数列的最大子段和)

    题干: 在蒜厂年会上有一个抽奖,在一个环形的桌子上,有 nn 个纸团,每个纸团上写一个数字,表示你可以获得多少蒜币.但是这个游戏比较坑,里面竟然有负数,表示你要支付多少蒜币.因为这些数字都是可见的,所 ...

  6. 单调队列以及单调队列优化DP

    单调队列定义: 其实单调队列就是一种队列内的元素有单调性的队列,因为其单调性所以经常会被用来维护区间最值或者降低DP的维数已达到降维来减少空间及时间的目的. 单调队列的一般应用: 1.维护区间最值 2 ...

  7. POJ 1821 Fence(单调队列优化DP)

    题解 以前做过很多单调队列优化DP的题. 这个题有一点不同是对于有的状态可以转移,有的状态不能转移. 然后一堆边界和注意点.导致写起来就很难受. 然后状态也比较难定义. dp[i][j]代表前i个人涂 ...

  8. 【单调队列优化DP】烽火传递 LibreOJ - 10180

    题目来源 点我进入提交题目 反思 因为目前在学习单调队列优化DP,所以会往单调队列上面想.然后犯了一个错误就是,认为这个题目只要用单调队列就可以完成,单调队列只是用来减少时间复杂度的,遇到了求最优解的 ...

  9. AcWing 1089 烽火传递 题解(动态规划—DP—单调队列优化DP)

    AcWing 1089 烽火传递 单调队列优化DP,思路比较简单,维护一个保持元素单调递增的单调队列,队首就是第i座烽火台能接收到的,代价最小的方案,加上第i座烽火台的代价就是这座烽火台的最小值 #i ...

最新文章

  1. 2018-12-04-Python全栈开发-day92-自动登录
  2. mysql 整个数据库_mysql 整个数据库
  3. Java LinkedList双向链表源码分析
  4. Gartner预测2019年全球IT支出将达到3.8万亿美元
  5. transition css_Transition 过渡
  6. 前端 vue 加载TIFF图片
  7. Nginx源码安装,配置开机自启
  8. Unity学习1——unity安装踩坑
  9. 四步成为人工智能产品经理
  10. uniapp加激励广告代码方法
  11. Ajax传参里面含有特殊字符
  12. Flink1.12-2021黑马 8 Flink高级特性和新特性
  13. php定义变量$3t=5,如何在Nexmo代码中设置php变量
  14. ubuntu18.04无法安装最新显卡驱动解决办法
  15. 大数据分析——暑期黑马《延禧攻略》到底有多火!
  16. Python开发qq批量登陆
  17. CS61A Lab 2
  18. SQL-包含中文字、英文、数字字符
  19. 基于高德地图实现可编辑的电子围栏功能【多边形围栏】
  20. 2021-11-26 WPF上位机 96-Modbus通信代码的封装

热门文章

  1. 微信小程序练手项目-音乐播放器
  2. 【JavaScript】浏览器
  3. Matlab 计算显色指数(Ra,R1-R15)、CCT、duv、Lux、XYZ三刺激值、CIE1931x、CIE1931y
  4. jedis设置过期时间
  5. Android Studio学习3
  6. php usc2,CSDN 免积分下载原理
  7. 汉诺塔完整代码及分析
  8. LTspice基础教程-022.从MOS管提取参数生成spice模型
  9. python称号_Python成为2018年度编程语言,遥遥领先于其他语言
  10. 数据库第十次作业-视图【带源码】