BZOJ 2436 NOI嘉年华(单调优化)
http://www.lydsy.com/JudgeOnline/problem.php?id=2436
题意:两个会场不能同时表演,但是同一个时间可以同时表演,要求让两个会场表演数量最小的最大,然后限制某一个必须表演,最小的要最大是多少。。
思路:先将时间离散化,预处理数组num[i][j],代表时间i到时间j一共包含了几个表演。
然后进行dp,pre[i][j],代表1~时间i,会场A表演了j个,此时会场B最多能表演几个。
pre[i][j]=max(pre[i][j+1],pre[k][j]+num[k][i],pre[k][j-num[k][i]]) 后两个分别代表这个区间的表演放到B,和这个区间的表演放到A,
suf[i][j]代表i~时间m,会场A表演了j个,此时会场B最多能表演几个,这个就是同理了
然后第一问的答案就是max(min(i,pre[m][i]))
对于第二问,我们考虑这样设计:
ans[i][j]=max(min(x+y+num[i][j],pre[i][x]+suf[j][y]))
这样的转移是n^4的,不能通过全部数据。
我们考虑令i和j固定,f[x][y]=min(x+y+num[i][j],pre[i][x]+suf[j][y])
再令x固定,y逐渐增大,发现f[x][y]是单峰的!,因此当f[x][y+1]<f[x][y]就可以break了。
原因是x+y+num[i][j]中只有y是在不断增大的,而pre[i][x]+suf[j][y]中suf[j][y]是不断减小的,由于是取min
因此会有一个瞬间x+y+num[i][j]和pre[i][x]+suf[j][y]会达到最接近,然后此时就是最大的答案,之前的和之后的都不是最优的!
#include<cstdio>
#include<cmath>
#include<iostream>
#include<cstring>
#include<algorithm>
struct node{
int s,e;
}a[];
int p[],ans[][],n,suf[][],pre[][],num[][];
int read(){
int t=,f=;char ch=getchar();
while (ch<''||ch>'') {if (ch=='-') f=-;ch=getchar();}
while (''<=ch&&ch<=''){t=t*+ch-'';ch=getchar();}
return t*f;
}
int find(int x){
int l=,r=p[];
while (l<=r){
int mid=(l+r)>>;
if (p[mid]==x) return mid;
else
if (p[mid]<x) l=mid+;
else r=mid-;
}
return ;
}
void init(){
n=read();
for (int i=;i<=n;i++)
a[i].s=read(),a[i].e=read()+a[i].s,p[++p[]]=a[i].s,p[++p[]]=a[i].e;
std::sort(p+,p++p[]);
int j=;
for (int i=;i<=p[];i++)
if (p[i]!=p[j]) p[++j]=p[i];
p[]=j;
for (int i=;i<=n;i++) a[i].s=find(a[i].s),a[i].e=find(a[i].e);
for (int i=;i<=p[];i++)
for (int j=i;j<=p[];j++)
for (int k=;k<=n;k++)
if (i<=a[k].s&&a[k].e<=j) num[i][j]++;
}
void dp(){
for (int i=;i<=;i++)
for (int j=;j<=;j++)
pre[i][j]=suf[i][j]=-;
pre[][]=suf[p[]+][]=;
for (int i=;i<=p[];i++)
for (int k=i;k>=;k--){
pre[i][k]=pre[i][k+];
for (int j=;j<=i-;j++)
pre[i][k]=std::max(pre[i][k],std::max(pre[j][k]+num[j][i],pre[j][k-num[j][i]]));
}
for (int i=p[];i>=;i--)
for (int k=p[]-i+;k>=;k--){
suf[i][k]=suf[i][k+];
for (int j=i+;j<=p[]+;j++)
suf[i][k]=std::max(suf[i][k],std::max(suf[j][k]+num[i][j],suf[j][k-num[i][j]]));
}
for (int i=;i<=p[];i++)
for (int j=i;j<=p[];j++){
int k=+p[]-j;
for (int x=;x<=i;x++)
for (int y=;y<=k;y++)
if (x+y<=n){
int sx=std::min(x+y+num[i][j],pre[i][x]+suf[j][y]);
if (sx<) break;
if (ans[i][j]<sx){
ans[i][j]=sx;
}else break;
}else break;
}
}
void Output(){
int Ans=;
for (int i=;i<=n;i++)
Ans=std::max(std::min(pre[p[]][i],i),Ans);
printf("%d\n",Ans);
for (int i=;i<=n;i++){
Ans=;
for (int j=;j<=p[];j++)
for (int k=j;k<=p[];k++)
if (j<=a[i].s&&a[i].e<=k) Ans=std::max(Ans,ans[j][k]);
printf("%d\n",Ans);
}
}
int main(){
init();
dp();
Output();
}
BZOJ 2436 NOI嘉年华(单调优化)的更多相关文章
- BZOJ 2436 Noi嘉年华(优化DP)
题目链接:http://61.187.179.132/JudgeOnline/problem.php?id=2436 题意:有一些活动,起始时间持续时间已知.有两个场地.每个活动最多只能在一个场地举行 ...
- bzoj 2436: [Noi2011]Noi嘉年华
Description NOI2011 在吉林大学开始啦!为了迎接来自全国各地最优秀的信息学选手,吉林大学决定举办两场盛大的 NOI 嘉年华活动,分在两个不同的地点举办.每个嘉年华可能包含很多个活动, ...
- 2436: [Noi2011]Noi嘉年华 - BZOJ
Description NOI2011 在吉林大学开始啦!为了迎接来自全国各地最优秀的信息学选手,吉林大学决定举办两场盛大的 NOI 嘉年华活动,分在两个不同的地点举办.每个嘉年华可能包含很多个活动, ...
- 【BZOJ 2436】 2436: [Noi2011]Noi嘉年华 (区间DP)
2436: [Noi2011]Noi嘉年华 Description NOI2011 在吉林大学开始啦!为了迎接来自全国各地最优秀的信息学选手,吉林大学决定举办两场盛大的 NOI 嘉年华活动,分在两个不 ...
- 【BZOJ2436】【NOI2011】NOI嘉年华(动态规划)
[BZOJ2436]NOI嘉年华(动态规划) 题面 BZOJ 题解 考虑第一问如何求解 发现状态与选择了哪些活动无关,只与时间有关 设\(f[i][j]\)表示前\(i\)个单位时间(离散后),一个嘉 ...
- [BZOJ 1563] [NOI 2009] 诗人小G(决策单调性)
[BZOJ 1563] [NOI 2009] 诗人小G(决策单调性) 题面 一首诗包含了若干个句子,对于一些连续的短句,可以将它们用空格隔开并放在一行中,注意一行中可以放的句子数目是没有限制的.小 G ...
- 【BZOJ-2436】嘉年华 DP + 优化
2436: [Noi2011]Noi嘉年华 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 529 Solved: 382[Submit][Statu ...
- [LOJ 2134][UOJ 132][BZOJ 4200][NOI 2015]小园丁与老司机
[LOJ 2134][UOJ 132][BZOJ 4200][NOI 2015]小园丁与老司机 题意 给定平面上的 \(n\) 个整点 \((x_i,y_i)\), 一共有两个问题. 第一个问题是从原 ...
- [LOJ 2083][UOJ 219][BZOJ 4650][NOI 2016]优秀的拆分
[LOJ 2083][UOJ 219][BZOJ 4650][NOI 2016]优秀的拆分 题意 给定一个字符串 \(S\), 求有多少种将 \(S\) 的子串拆分为形如 AABB 的拆分方案 \(| ...
随机推荐
- list append 总是复制前面的参数,而不复制最后一个参数
append 总是复制前面的参数,而不复制最后一个参数 (define a1 '(1 2 3)) (define a2 '(a b c)) (define x (append a1 a2)) x ; ...
- 转:Android模拟器连接电脑网络
原文地址:http://www.it165.net/pro/html/201212/4444.html 第一步: 在命令行(就是开始——运行——输入cmd)模式下输入adb shell命令一般会报两种 ...
- HDU4821---字符串hash,map判重
这是2013年长春区域赛的铜牌题...然而第一次做的时候一直觉得会超时的..最后才知道并没有想象中的那么恐怖: 这题有两个注意的地方: (1)h[i] = h[i-1] * seed + s[i] - ...
- Python字典的操作与使用
字典的描述 字典是一种key-value的数据类型,使用就像我们上学用的字典,通过拼音(key)来查对应字的详细内容(value). 字典的特性 1.字典是无序的(不像列表一样有下标,它通过key来获 ...
- Thrift的安装和简单演示样例
本文仅仅是简单的解说Thrift开源框架的安装和简单使用演示样例.对于具体的解说,后面在进行阐述. Thrift简述 ...
- linux下使用mutt发送带附件的邮件
echo "hello"|mutt -s "world" -a hack.jpg -- name@address.com
- 未知宽高div水平垂直居中3种方法
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> </head&g ...
- 应用highcharts做直观数据统计
最近在看上了统计类的东东,发现以前端图表神器:highcharts Highcharts是一款功能强大.开源.美观.图表丰富.兼容绝大多数浏览器的纯Js图表库,Highcharts支持的图表类型有直线 ...
- pagefile.sys怎么删除
pagefile.sys是虚拟内存文件,目地是使用一部分硬盘空间来充当内存使用.当一个程序请求的内存空间大于物理内存时,就需要pagefile.sys文件来提供较大的虚拟内存,从而满足程序对大内存的需 ...
- [C#][Database]C#通过ODBC以自定义端口连接数据库
数据库端的配置暂且不说,比较简单,新建用户并开启相应连接权限即可. 通过ODBC连接数据库,重点在于Connection String的书写,在此可以查到几乎所有类型的Data Server的Conn ...