LINK:NOI 嘉年华

一道质量非常高的dp题目。

考虑如何求出第一问 容易想到dp.

按照左端点排序/右端点排序状态还是很难描述。

但是我们知道在时间上肯定是一次选一段 所以就可以直接利用时间点来dp.

直接将时间离散再做 因为有两个元素使得最大的最小 二分是无意义的。

每次选择是一段所以没必要知道上次选到的时间点在哪 直接枚举上次决策。

分别记录两个地方的值是否存在也是可以优化的 可以只记录一个然后第二个变成最多拿到多少即可。

这样就有状态\(f_{i,j}\)表示到了i这个时间点第一个的值为j的时候第二个的最大值。

转移枚举k 然后预处理\(c_{i,j}\)表示这段时间的任务数即可。

复杂度\(n^3\)

考虑第二问。强制选择某个点 在dp中是很难做到的 所以可以考虑强行将某个区间给第一个会场然后求出第二个会场的最大值。

强行给的话这个地方可以使用前后包夹做 即再做一个后缀dp g数组。

那么强行包含\(l,r\)的最大dp值就是 \(ans_{l,r}=\sum_{x}\sum_{y}max(x+y+c_{l,r},f_{l,x}+g_{r,y})\)

求出这个东西看似是\(n^4\)的 实际上随着x的增大y是不增的。

证明这一点可以进行比较繁杂的分类讨论 不过可以比较直观的想出来。这里不再赘述。

所以可以优化到\(n^3\).

考虑最后的答案 对于一个询问l,r 答案不一定是\(l,r\) 因为此时是把l r单独给抽出来了。

可能一些大的区间一起并且包含其可能是最优的 所以此时枚举包含这个区间的一些区间取max即可。

总复杂度\(n^3\).

code
//#include<bits\stdc++.h>
#include<iostream>
#include<iomanip>
#include<cstdio>
#include<cstring>
#include<string>
#include<ctime>
#include<cmath>
#include<cctype>
#include<cstdlib>
#include<queue>
#include<deque>
#include<stack>
#include<vector>
#include<algorithm>
#include<utility>
#include<bitset>
#include<set>
#include<map>
#define ll long long
#define db double
#define INF 1000000000
#define ldb long double
#define pb push_back
#define put_(x) printf("%d ",x);
#define get(x) x=read()
#define gt(x) scanf("%d",&x)
#define gi(x) scanf("%lf",&x)
#define put(x) printf("%d\n",x)
#define putl(x) printf("%lld\n",x)
#define gc(a) scanf("%s",a+1)
#define rep(p,n,i) for(RE int i=p;i<=n;++i)
#define go(x) for(int i=lin[x],tn=ver[i];i;tn=ver[i=nex[i]])
#define fep(n,p,i) for(RE int i=n;i>=p;--i)
#define vep(p,n,i) for(RE int i=p;i<n;++i)
#define pii pair<int,int>
#define mk make_pair
#define RE register
#define P 1000000007
#define gf(x) scanf("%lf",&x)
#define pf(x) ((x)*(x))
#define uint unsigned long long
#define ui unsigned
#define EPS 1e-4
#define sq sqrt
#define S second
#define F first
#define mod 1000000007
using namespace std;
char buf[1<<15],*fs,*ft;
inline char getc()
{
return (fs==ft&&(ft=(fs=buf)+fread(buf,1,1<<15,stdin),fs==ft))?0:*fs++;
}
inline int read()
{
RE int x=0,f=1;RE char ch=getc();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getc();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getc();}
return x*f;
}
const int MAXN=410;
int n,m,cnt;
int b[MAXN];
int f[MAXN][MAXN],g[MAXN][MAXN],c[MAXN][MAXN],ans[MAXN][MAXN];
struct wy{int l,r;}t[MAXN];
int main()
{
//freopen("1.in","r",stdin);
get(n);
rep(1,n,i)
{
int get(l),get(r)+l;
t[i]=(wy){l,r};
b[++cnt]=l;b[++cnt]=r;
}
sort(b+1,b+1+cnt);
rep(1,cnt,i)if(i==1||b[i]!=b[i-1])b[++m]=b[i];
rep(1,n,i)
{
t[i].l=lower_bound(b+1,b+1+m,t[i].l)-b;
t[i].r=lower_bound(b+1,b+1+m,t[i].r)-b;
rep(1,t[i].l,j)rep(t[i].r,m,k)++c[j][k];
//cout<<t[i].l<<' '<<t[i].r<<endl;
}
memset(f,0xcf,sizeof(f));
memset(g,0xcf,sizeof(g));
f[1][0]=0;g[m][0]=0;
rep(2,m,i)rep(0,c[1][i],j)
{
rep(1,i-1,k)
{
f[i][j]=max(f[i][j],f[k][j]+c[k][i]);
if(j>=c[k][i])f[i][j]=max(f[i][j],f[k][j-c[k][i]]);
}
//cout<<i<<' '<<j<<' '<<f[i][j]<<endl;
}
fep(m-1,1,i)rep(0,c[i][m],j)rep(i+1,m,k)
{
g[i][j]=max(g[i][j],g[k][j]+c[i][k]);
if(j>=c[i][k])g[i][j]=max(g[i][j],g[k][j-c[i][k]]);
}
rep(1,m,i)
{
rep(i,m,j)
{
int y=n;
rep(0,n,x)
{
while(y&&min(c[i][j]+x+y,f[i][x]+g[j][y])<=min(c[i][j]+x+y-1,f[i][x]+g[j][y-1]))--y;
ans[i][j]=max(ans[i][j],min(c[i][j]+x+y,f[i][x]+g[j][y]));
}
//cout<<i<<' '<<j<<' '<<ans[i][j]<<endl;
}
}
int ww=0;
rep(1,n,i)ww=max(ww,min(i,f[m][i]));
put(ww);
rep(1,n,i)
{
ww=0;
rep(1,t[i].l,j)rep(t[i].r,m,k)ww=max(ww,ans[j][k]);
put(ww);
}
return 0;
}

luogu P1973 [NOI2011]NOI 嘉年华 dp的更多相关文章

  1. 洛谷P1973 [NOI2011]Noi嘉年华(动态规划,决策单调性)

    洛谷题目传送门 DP题怕是都要大大的脑洞...... 首先,时间那么大没用,直接离散化. 第一问还好.根据题意容易发现,当一堆活动的时间有大量重叠的时候,更好的办法是把它们全部安排到一边去.那么我们转 ...

  2. 洛谷P1973 [NOI2011]Noi嘉年华(决策单调性)

    传送门 鉴于FlashHu大佬讲的这么好(而且我根本不会)我就不再讲一遍了->传送 //minamoto #include<iostream> #include<cstdio& ...

  3. cogs 1377. [NOI2011] NOI嘉年华 (dp

    题意:给你n个活动的起止时间,要你从中选一些活动在2个会场安排(不能有两个活动在两个会场同时进行),使活动较少的会场活动数最大,以及在某个活动必须选择的前提下,求该答案. 思路:由于n很小,时间很大, ...

  4. P1973 [NOI2011]Noi嘉年华

    传送门 首先可以把时间区间离散化 然后求出 $cnt[l][r]$ 表示完全在时间 $[l,r]$ 之内的活动数量 设 $f[i][j]$ 表示当前考虑到时间 $i$,第一个会场活动数量为 $j$ 时 ...

  5. 【BZOJ 2436】 2436: [Noi2011]Noi嘉年华 (区间DP)

    2436: [Noi2011]Noi嘉年华 Description NOI2011 在吉林大学开始啦!为了迎接来自全国各地最优秀的信息学选手,吉林大学决定举办两场盛大的 NOI 嘉年华活动,分在两个不 ...

  6. 2436: [Noi2011]Noi嘉年华 - BZOJ

    Description NOI2011 在吉林大学开始啦!为了迎接来自全国各地最优秀的信息学选手,吉林大学决定举办两场盛大的 NOI 嘉年华活动,分在两个不同的地点举办.每个嘉年华可能包含很多个活动, ...

  7. bzoj 2436: [Noi2011]Noi嘉年华

    Description NOI2011 在吉林大学开始啦!为了迎接来自全国各地最优秀的信息学选手,吉林大学决定举办两场盛大的 NOI 嘉年华活动,分在两个不同的地点举办.每个嘉年华可能包含很多个活动, ...

  8. BZOJ2436 [Noi2011]Noi嘉年华 【dp】

    题目链接 BZOJ2436 题解 看这\(O(n^3)\)的数据范围,可以想到区间\(dp\) 发现同一个会场的活动可以重叠,所以暴力求出\(num[l][r]\)表示离散化后\([l,r]\)的完整 ...

  9. bzoj2436: [Noi2011]Noi嘉年华

    我震惊了,我好菜,我是不是该退役(苦逼) 可以先看看代码里的注释 首先我们先考虑一下第一问好了真做起来也就这个能想想了 那么离散化时间是肯定的,看一手范围猜出是二维DP,那对于两个会场,一个放自变量, ...

随机推荐

  1. 区间dp(低价回文)

    [题目大意] 追踪每头奶牛的去向是一件棘手的任务,为此农夫约翰安装了一套自动系统.他在每头牛身上安装了一个电子身份标签,当奶牛通过扫描器的时候,系统可以读取奶牛的身份信息.目前,每个身份都是由一个字符 ...

  2. POJ3057 Evacuation 二分图匹配+最短路

    POJ3057 Evacuation 二分图匹配+最短路 题目描述 Fires can be disastrous, especially when a fire breaks out in a ro ...

  3. 古有七步成诗,今有六步完成DevOps上华为云DevCloud实践

    引言: 在“DevOps能力之屋(Capabilities House of DevOps)”中,华为云DevCloud提出(工程方法+最佳实践+生态)×工具平台=DevOps能力.华为云DevClo ...

  4. 一题搞定static关键字

    基础不牢,地动山摇 开篇一道题,考察代码执行顺序: public class Parent { static { System.out.println("Parent static init ...

  5. C#中Linq查询List与DataTable和Dictionary

    查询DataTable返回List List<string> listNation = dtNation.AsEnumerable().Select(d => d.Field< ...

  6. Linux 下载工具推荐: Motrix && qbittorrent

    Linux下载介绍 Linux下其实下载工具还是蛮多的, 命令行的wget,curl,aria2,甚至于apt 但是个人日常使用下还是有图形化界面比较方便易用.大多数教程里推荐的Uget,可能是我也不 ...

  7. JVM 学习笔记(四)

    回顾: 在之前的文章中,我们主要体现了当堆内存设置的比较小的情况下,比如:-Xmx20M -Xms20M,在项目运行的过程中,不断往内存中去添加对象, 这时候就会出现OOM,也就是内存溢出,本文章将展 ...

  8. nginx随机模块—random_index

    nginx 随机模板参数: 这个模块他的作用于只有在location中,具体写法如下 location / { root html/code; andom_index on; #index index ...

  9. 小书MybatisPlus第5篇-Active Record模式精讲

    本文为一个系列中的第五节,前四节访问如下地址: 小书MybatisPlus第1篇-整合SpringBoot快速开始增删改查 小书MybatisPlus第2篇-条件构造器的应用及总结 小书Mybatis ...

  10. 少儿编程:python趣味编程第一课

    本文仅针对8-16岁的青少年,所以流程是按如何去教好中小学生走的,并不适合成人找工作学习,因为进度也是按照青少年走的 大家好,我是C大叔,从事少儿编程行业三年有余(2016年从事少儿编程行业,少儿编程 ...