洛谷P1973 [NOI2011]Noi嘉年华(动态规划,决策单调性)
2018-08-13 17:44
375 查看
洛谷题目传送门
DP题怕是都要大大的脑洞。。。。。。
首先,时间那么大没用,直接离散化。
第一问还好。根据题意容易发现,当一堆活动的时间有大量重叠的时候,更好的办法是把它们全部安排到一边去。那么我们转移的时候也肯定是要一块一块地转移啦。
设\(tot_{l,r}\)为完全被包含在\(l-r\)时间内活动总数,直接\(O(n^3)\)暴力求就好了。
设\(pre_{i,j}\)为时间\(1-i\)内一边选\(j\)个时,另一边能选的最大值。枚举一块转移的话,我们的方程应该写成这样:
\[pre_ {i,j}=\max\limits_{k=1}^i\{pre_ {k,j}+tot_{k,i},pre _{k,j-tot _{k,i}}\}\]
(显然两种情况都要考虑)
然后答案就是\(\max\limits_{j=1}^n\{\min(pre_{m,j},j)\}\)啦(\(m\)为离散化后的时间总长,不会超过\(2n\))
这个数组为什么要叫\(pre\)呢?这是个前缀DP值。为了第二问,我们还要做个后缀DP,\(suf_{i,j}\)表示时间\(i-m\)内一边选\(j\)个时,另一边能选的最大值,跟\(pre\)几乎一样的转移,也是\(O(n^3)\)的。
对于第二问,我们显然可以肯定\(s_i-t_i\)之内的活动都被一边选走了。至于\(s_i\)之前和\(t_i\)以后选了多少,我们也只好枚举。设\(f_{l,r}\)为一边强制选\(l-r\)之间所有活动时最优的最小值,假定这一边在前面选了\(x\)个,在后面选了\(y\)个,另一边最多能选多少也就知道了,有方程
\[f_{l,r}=\max\limits_{x=1}^m\max\limits_{y=1}^m\{\min(x+tot_{l,r}+y,pre_{l,x}+suf_{r,y})\}\]
然后第\(i\)个的答案就是\(f_{s_i,t_i}\)么?注意千万别掉入这个误区!\(pre\)和\(suf\)只是保证了局部最优,而没有保证全局最优。要说人话的话,就是可能有一个活动跨过了\(s_i\),然而\(f_{s_i,t_i}\)并没有统计到它,只有扩大强制选的区间使得能够包含它,才能统计到最优解。于是需要枚举强制选区间了,\(ans_i=\max\limits_{l=1}^{s_i}\max\limits_{r=t_i}^m\{f_{l,r}\}\)
这样的话,整个\(f\)都必须要算出来,上面的枚举算法就变成\(O(n^4)\)了,跑不动。
点开标签发现有单调队列?!蒟蒻就往单调性上面想了想,于是就有了一个结论:设枚举\(x\)时有一个使答案最优的\(y\),那么当\(x\)增大时,如果\(y\)也增大那么答案不会更优。观察上面那个式子\(\min(x+tot_{l,r}+y,pre_{l,x}+suf_{r,y})\),那么因为\(pre,suf\)都是递减的,所以很显然我们不能让\(x,y\)变大而\(pre,suf\)变小。
于是,实现的时候,只要把\(y\)从大往小扫了,并不需要什么单调队列来维护它。
DP题怕是都要大大的脑洞。。。。。。
首先,时间那么大没用,直接离散化。
第一问还好。根据题意容易发现,当一堆活动的时间有大量重叠的时候,更好的办法是把它们全部安排到一边去。那么我们转移的时候也肯定是要一块一块地转移啦。
设\(tot_{l,r}\)为完全被包含在\(l-r\)时间内活动总数,直接\(O(n^3)\)暴力求就好了。
设\(pre_{i,j}\)为时间\(1-i\)内一边选\(j\)个时,另一边能选的最大值。枚举一块转移的话,我们的方程应该写成这样:
\[pre_ {i,j}=\max\limits_{k=1}^i\{pre_ {k,j}+tot_{k,i},pre _{k,j-tot _{k,i}}\}\]
(显然两种情况都要考虑)
然后答案就是\(\max\limits_{j=1}^n\{\min(pre_{m,j},j)\}\)啦(\(m\)为离散化后的时间总长,不会超过\(2n\))
这个数组为什么要叫\(pre\)呢?这是个前缀DP值。为了第二问,我们还要做个后缀DP,\(suf_{i,j}\)表示时间\(i-m\)内一边选\(j\)个时,另一边能选的最大值,跟\(pre\)几乎一样的转移,也是\(O(n^3)\)的。
对于第二问,我们显然可以肯定\(s_i-t_i\)之内的活动都被一边选走了。至于\(s_i\)之前和\(t_i\)以后选了多少,我们也只好枚举。设\(f_{l,r}\)为一边强制选\(l-r\)之间所有活动时最优的最小值,假定这一边在前面选了\(x\)个,在后面选了\(y\)个,另一边最多能选多少也就知道了,有方程
\[f_{l,r}=\max\limits_{x=1}^m\max\limits_{y=1}^m\{\min(x+tot_{l,r}+y,pre_{l,x}+suf_{r,y})\}\]
然后第\(i\)个的答案就是\(f_{s_i,t_i}\)么?注意千万别掉入这个误区!\(pre\)和\(suf\)只是保证了局部最优,而没有保证全局最优。要说人话的话,就是可能有一个活动跨过了\(s_i\),然而\(f_{s_i,t_i}\)并没有统计到它,只有扩大强制选的区间使得能够包含它,才能统计到最优解。于是需要枚举强制选区间了,\(ans_i=\max\limits_{l=1}^{s_i}\max\limits_{r=t_i}^m\{f_{l,r}\}\)
这样的话,整个\(f\)都必须要算出来,上面的枚举算法就变成\(O(n^4)\)了,跑不动。
点开标签发现有单调队列?!蒟蒻就往单调性上面想了想,于是就有了一个结论:设枚举\(x\)时有一个使答案最优的\(y\),那么当\(x\)增大时,如果\(y\)也增大那么答案不会更优。观察上面那个式子\(\min(x+tot_{l,r}+y,pre_{l,x}+suf_{r,y})\),那么因为\(pre,suf\)都是递减的,所以很显然我们不能让\(x,y\)变大而\(pre,suf\)变小。
于是,实现的时候,只要把\(y\)从大往小扫了,并不需要什么单调队列来维护它。
#include<cstdio> #include<algorithm> #define RG register #define R RG int #define G c=getchar() #define Upd(A,L,R) {chkmx(A[i][j],A[k][j]+tot[L][R]); \ if(j>=tot[L][R])chkmx(A[i][j],A[k][j-tot[L][R]]);} #define Calc(y) min(x+tot[l][r]+y,pre[l][x]+suf[r][y]) using namespace std; const int N=209,M=409,INF=1e9; int s ,t ,b[M],tot[M][M],pre[M] ,suf[M] ,f[M][M]; inline int in(){ RG char G; while(c<'-')G; R x=c&15;G; while(c>'-')x=x*10+(c&15),G; return x; } inline int min(R x,R y){return x<y?x:y;} inline void chkmx(R&x,R y){if(x<y)x=y;} int main(){ R n=in(),m=0,i,j,k,l,r,x,y,p0,p1,ans; for(i=1;i<=n;++i){ b[++m]=s[i]=in(); b[++m]=t[i]=in()+s[i]; } sort(b+1,b+m+1);//离散化 m=unique(b+1,b+m+1)-b-1; for(i=1;i<=n;++i){ s[i]=lower_bound(b+1,b+m+1,s[i])-b; t[i]=lower_bound(b+1,b+m+1,t[i])-b; for(l=1;l<=s[i];++l)//tot暴力求 for(r=m;r>=t[i];--r)++tot[l][r]; } for(i=1;i<=m;++i)//注意初始化 for(j=1;j<=n;++j)pre[i][j]=suf[i][j]=-INF; for(i=1;i<=m;++i) for(j=0;j<=tot[1][i];++j) for(k=1;k<=i;++k)Upd(pre,k,i); for(i=m;i;--i)//转移很相似,搞了个宏定义 for(j=0;j<=tot[i][m];++j) for(k=i;k<=m;++k)Upd(suf,i,k); for(l=1;l<=m;++l) for(r=l+1;r<=m;++r) for(y=n,x=0;x<=n;++x){ p0=Calc(y);//p0为最优决策,p1为当前决策 while(y&&p0<=(p1=Calc(y-1)))p0=p1,--y; chkmx(f[l][r],Calc(y)); } ans=0; for(j=1;j<=n;++j)chkmx(ans,min(pre[m][j],j)); printf("%d\n",ans); for(i=1;i<=n;++i){ ans=0; for(l=1;l<=s[i];++l) for(r=m;r>=t[i];--r)chkmx(ans,f[l][r]); printf("%d\n",ans); } return 0; }
相关文章推荐
- 洛谷P1973 [NOI2011]Noi嘉年华(决策单调性)
- ★【动态规划】【单调性优化】【NOI2011】NOI嘉年华
- 洛谷P3515 [POI2011]Lightning Conductor(动态规划,决策单调性,单调队列)
- [NOI2011]Noi嘉年华(动态规划及单调性优化)
- 【动态规划】【决策单调性优化】【NOI2004】小H的小屋
- noi 2011 noi嘉年华 动态规划
- 洛谷P3515 [POI2011]Lightning Conductor(决策单调性)
- 洛谷 P1815 蠕虫游戏 _NOI导刊2011提高(02)
- 洛谷 P1844 阅览室_NOI导刊2011提高(12)
- 2436: [Noi2011]Noi嘉年华 - BZOJ
- bzoj 2436: [Noi2011]Noi嘉年华 (dp)
- bzoj 2436: [Noi2011]Noi嘉年华
- 不失一般性和快捷性地判定决策单调(洛谷P1912 [NOI2009]诗人小G)(动态规划,决策单调性,单调队列)
- 【bzoj2216】[Poi2011]Lightning Conductor 决策单调性+整体二分
- bzoj 4709: [Jsoi2011]柠檬(分段DP+决策单调性)
- 洛谷P1809 过河问题_NOI导刊2011提高(01)
- 洛谷CF868F Yet Another Minimization Problem(动态规划,决策单调性,分治)
- 洛谷P1912 [NOI2009]诗人小G(决策单调性)
- [BZOJ 2216][Poi2011]Lightning Conductor:DP决策单调性
- bzoj 2216: [Poi2011]Lightning Conductor(DP决策单调性)