洛谷P1973 [NOI2011]Noi嘉年华(动态规划,决策单调性)
DP题怕是都要大大的脑洞。。。。。。
首先,时间那么大没用,直接离散化。
第一问还好。根据题意容易发现,当一堆活动的时间有大量重叠的时候,更好的办法是把它们全部安排到一边去。那么我们转移的时候也肯定是要一块一块地转移啦。
设\(tot_{l,r}\)为完全被包含在\(l-r\)时间内活动总数,直接\(O(n^3)\)暴力求就好了。
设\(pre_{i,j}\)为时间\(1-i\)内一边选\(j\)个时,另一边能选的最大值。枚举一块转移的话,我们的方程应该写成这样:
\]
(显然两种情况都要考虑)
然后答案就是\(\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\)个,另一边最多能选多少也就知道了,有方程
\]
然后第\(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[N],t[N],b[M],tot[M][M],pre[M][N],suf[M][N],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嘉年华(动态规划,决策单调性)的更多相关文章
- 洛谷P1973 [NOI2011]Noi嘉年华(决策单调性)
传送门 鉴于FlashHu大佬讲的这么好(而且我根本不会)我就不再讲一遍了->传送 //minamoto #include<iostream> #include<cstdio& ...
- luogu P1973 [NOI2011]NOI 嘉年华 dp
LINK:NOI 嘉年华 一道质量非常高的dp题目. 考虑如何求出第一问 容易想到dp. 按照左端点排序/右端点排序状态还是很难描述. 但是我们知道在时间上肯定是一次选一段 所以就可以直接利用时间点来 ...
- 洛谷P3515 [POI2011]Lightning Conductor(决策单调性)
题意 已知一个长度为n的序列a1,a2,...,an. 对于每个1<=i<=n,找到最小的非负整数p满足 对于任意的j, aj < = ai + p - sqrt(abs(i-j)) ...
- 洛谷 P3515 [ POI 2011 ] Lightning Conductor —— 决策单调性DP
题目:https://www.luogu.org/problemnew/show/P3515 决策单调性... 参考TJ:https://www.cnblogs.com/CQzhangyu/p/725 ...
- P1973 [NOI2011]Noi嘉年华
传送门 首先可以把时间区间离散化 然后求出 $cnt[l][r]$ 表示完全在时间 $[l,r]$ 之内的活动数量 设 $f[i][j]$ 表示当前考虑到时间 $i$,第一个会场活动数量为 $j$ 时 ...
- 洛谷P3724 [AH2017/HNOI2017]大佬(决策单调性)
传送门 这个思路很妙诶->这里 以下为了方便,我把自信说成血量好了 虽然表面上看起来每一天有很多种选择,然而我们首先要保证的是不死,然后考虑不死的情况下最多能拿出多少天来进行其他操作.不死可以d ...
- 【BZOJ 2436】 2436: [Noi2011]Noi嘉年华 (区间DP)
2436: [Noi2011]Noi嘉年华 Description NOI2011 在吉林大学开始啦!为了迎接来自全国各地最优秀的信息学选手,吉林大学决定举办两场盛大的 NOI 嘉年华活动,分在两个不 ...
- bzoj 2436: [Noi2011]Noi嘉年华
Description NOI2011 在吉林大学开始啦!为了迎接来自全国各地最优秀的信息学选手,吉林大学决定举办两场盛大的 NOI 嘉年华活动,分在两个不同的地点举办.每个嘉年华可能包含很多个活动, ...
- 2436: [Noi2011]Noi嘉年华 - BZOJ
Description NOI2011 在吉林大学开始啦!为了迎接来自全国各地最优秀的信息学选手,吉林大学决定举办两场盛大的 NOI 嘉年华活动,分在两个不同的地点举办.每个嘉年华可能包含很多个活动, ...
随机推荐
- java算法----排序----(5)归并排序
package log; import java.util.Arrays; public class Test4 { /** * java算法---归并排序 * * @param args */ pu ...
- sql 语言
sql 语言 DDL DDL 全称 Data Definition Language,即数据定义语言. DATABASE 创建数据库 CREATE DATABASE 语句用于创建数据库. CREATE ...
- 4.5《想成为黑客,不知道这些命令行可不行》(Learn Enough Command Line to Be Dangerous)—第四章小结
本章相关重要命令总结在Table 6. 命令 描述 示例 mkdir <name> 创建某目录 $ mkdir foo pwd 显示当前所在目录 $ pwd cd <dir> ...
- LOJ2537 PKUWC2018 Minimax 树形DP、线段树合并
传送门 题意:自己去看 首先可以知道,每一个点都有几率被选到,所以$i$与$V_i$的关系是确定了的. 所以我们只需要考虑每一个值的取到的概率. 很容易设计出一个$DP$:设$f_{i,j}$为在第$ ...
- Vue-认识状态管理vuex
vuex是一个专门为vue.js设计的状态管理模式,并且也可以使用devtools进行调试,可以多个组件共享状态.简单来说,就是共享的状态用state来存放,用mutations来操作state,但是 ...
- 性能调优之vmstat命令
vmstat是Virtual Meomory Statistics(虚拟内存统计)的缩写,可对操作系统的虚拟内存.进程.IO读写.CPU活动等进行监视.它是对系统的整体情况进行统计,不足之处是无法对某 ...
- Visual Studio2017 数据库架构比较
一.前言 开发的时候在测试服务器上和线网服务器上面都有我们的数据库,当我们在线网上面修改或者新增一些字段后,线网的数据库也需要更新,这个时候根据表的修改记录,然后在线网上面一个一个增加修改很浪费效率而 ...
- SpringMvc返回Json调试
spring-web-5.0.6.RELEASE.jar!/org/springframework/web/method/support/HandlerMethodReturnValueHandler ...
- 2丶利用NABCD模型进行竞争性需求分析
确定项目:公交查询系统 分析小组:在路上 选择比努力更重要.一个项目成功自然离不开组员们的努力.但是,光努力是不够的.还需要用户有需求,能快速实现. 这些东西,看似很虚,却能让我们少走不少弯路.做项目 ...
- Eclipse的Jar包解压出System.js里String与Boolean定义分号可有可无吗?
Eclipse的Jar包解压出System.js里String与Boolean定义分号可有可无吗? org.eclipse.wst.jsdt.core_1.3.300.v201410221502\li ...