2011年6月29日
摘要:
题目大意:给你N个有序数对(Ai, Bi),以及一个限制Limit。要求你把这些数对分成若干个连续区间,使得下面的两个条件得到满足:一、对于任意的p < q,如果p与q属于不同的区间,有Bp > Aq。二、设Mi为第i个区间中最大的A值。满足∑(Mi, 1≤i≤P)≤Limit,其中P是区间总数。设Si是第i个区间中所有B的和。求满足上面条件的所有划分方案中,能够得到的最小的min(Si, 1≤i≤P)是多少。对于任意的p < q,如果p与q属于不同的区间,有Bp > Aq。换句话说就是如果p<q且Bp<Aq则p,q必在同一个区间。那么我们把必须在一起的都捆 阅读全文
2011年6月27日
摘要:
朴素的话f[i]=f[j]+maxdata[j+1,i],是n^2的,必须优化。我们发现对于递增的i,其决策与是不减的,我们想到了单调队列。我们发现,有效的决策是一个递减的序列,这是因为f[i]是单调的。而且如果维护这样的队列,就不需要事先预处理做RMQ了。那么这道题有什么玄机呢?有的,这道题目维护单调队列时的条件不能直接导致队首的值最优,这意味着如果我们扫一遍取最优值的话还是n^2。所以我们就要借助数据结构优化了,带索引的堆或者平衡树都可以,关键是要随着单调队列元素的增删而增删。复杂度降为nlogn。决策下界处需要单独特判,而且插入和删除BST元素的时候也要仔细再仔细。//By YY_Mor 阅读全文
2011年6月24日
摘要:
先想出朴素的DP转移,设f[i,j]为在使用i号机器完成第j工序所需最短时间sum[i,a,b]为i机器从工序a工作到b的时间f[i,j]=min(f[i',j']+sum[i,j',j]+K)(i'<>i,j-j'<=L)这样的话时间复杂度是O(N^2*M*L),会死得很惨怎么办呢?我们发现,N的值是很小的,这就促使我们产生了把每台机器单独考虑的想法我们现在只考虑计算f[1,j]的情况,那么f[1,j]=min(f[i',j']+sum[1,j',j]+K)=min(f[i',j']-sum[1 阅读全文
2011年6月23日
摘要:
看到这道题之后设计出的状态是f[i,j]为第i天各种交易之后持有j股票的情况下所能获得的最大利益。那么转移应该是f[i,j]=f[i',j']+(j'-j)*x[i]其中i-i'>W,当j'>j时,j'-j<=BS[i],x[i]=BP[i]。当j>j'时,j-j'<=AS[i],x[i]=AP[i]这样的复杂度是T^2*MaxP^2我们观察到,对于i和i+1,其决策域基本上是重复的,于是将f[i,j]的状态改为前i天各种交易之后持有j股票的情况下所能获得的最大利益。这样f[i,j]=max(f[i- 阅读全文
2011年6月22日
摘要:
这道题很有意思,需要巧妙地套用单调队列首先我们要明确几件事情1.假设我们现在知道序列(i,j)是符合标准的,那么如果第j+1个元素不比(i,j)最大值大也不比最小值小,那么(i,j+1)也是合法的2.如果(i,j)不合法的原因是差值比要求小,那在(i,j)范围内的改动是无效的,需要加入j+1元素充当最大值或者最小值才可能获得合法的序列3.假设序列(i,j)的差值比要求大,那么我们必须将其中的最大值或者最小值从序列中删除出去,才可能获得一个合法的序列,只往里加入元素是不可能令序列合法的基于以上几点考虑,我们可以利用单调队列完成我们的算法。设定一个变量ST作为当前合法序列的开端(对于一个序列(i, 阅读全文
摘要:
也是单调队列的基本题,首先要把N的环拆成2N的链,设f[i]是以第i个元素结尾的序列的最大和,f[i]=max(sum[j+1,i])=max(sum[1,i]-sum[1,j])=sum[1,i]-min(sum[1,j])(i-j<=K),这样就可以用单调队列维护了//By YY_More#include<cstdio>#include<cstring>int D[200010],sum[200010],L,R,T,n,k,p,q,max;int main(){ scanf("%d",&T); while (T-->0){ s 阅读全文
摘要:
这道是NOI2005的原题吧这道题乍一看,很容易设计出状态f[T][N][M],而且鉴于T有40000,K只有200,倾斜方向也是基于K的,因此把状态设计成f[K][N][M],即第K段时间滑到(N,M)位置的最大滑行距离。设p[K]为第K段时间的持续长度,这样的话,根据倾斜方向不同,我们得到了四种转移方程。f[K][N][M]=max(f[K-1][i][j]+dist)(dist<=p[K])向上时:j=M,i>=N,dist=i-N向下时:j=M,i<=N,dist=N-i向左时:i=N,j>=M,dist=j-M向右时:i=N,j<=M,dist=M-j可 阅读全文
摘要:
这是一道最最基础的使用双端队列优化的题目。题目的意思就是求出指定长度子序列的最大值和最小值。如果说硬要弄一个方程的话,那就是f[i]=max/min(a[j]) (f[i]指以i结尾的子序列,a[j]指原序列中第k个元素。i-k+1<=j<=i)显然我们可以通过单调队列来维护最大值和最小值,复杂度O(n)按理说双端队列应该有两个域,一个存下标,一个存关键值,但是这道题中关键值很容易从原序列中取出,所以就省掉了这个域,在这里提醒一下刚接触单调队列的人。当然,这个数据范围暴力RMQ也可以过,其实也不是很暴力啦,但是跟O(n)的算法比就不太优美了。提示:在POJ上做这道题的时候,如果你超 阅读全文
2011年6月21日
摘要:
动规优化里面也要大量使用二分查找,我觉得这道题对二分查找考察的很好我的做法是在字典序中查找不小于输入字串的最小字串,对于它及它之后的字串判断是否以输入字串为前缀。由于题目中说有重复的字串,我给重复的字串加了个标记。//By YY_More#include<cstdio>#include<cstring>#include<algorithm>using namespace std;struct node{ char st[30];}; node f[10010];bool nok[10010];int n,k,p,q;char str[30];bool com 阅读全文
摘要:
这几天都在琢磨动态规划的单调性优化了,必然会用到很多队列的操作所以先搞一道队列的模拟水题主要还是想试试高亮代码效果怎么样。。。这个代码还是之前用pascal写的。虽然写的很随意,但是时间空间,尤其是代码长度都都排在前面。//By YY_Moretype que=record data,pos:longint end;var n,l,r,m,k,h:longint; s:string; d:array[0..1000000]of que;begin readln(n); while n>0 do begin readln(s); if s[1]='E' then dec(n 阅读全文
|