http://www.elijahqi.win/archives/2987
Description
农夫约翰为他的奶牛们开了一个游泳池,他认为这将有助于他们放松和生产更多的牛奶。为确保安全,他请了N只
牛做救生员,每只牛都有一个工作时间,为一些连续的时间间隔为了简单起见,泳池每天从时间0打开到到10^9,
所以每个区间都可以用两个整数来描述,给定的这两个整数就是区间的开始和结束时刻。例如,一个救生员从t =
4时开始工作和在t=7时结束,共覆盖三个时间单位(注意端点也是覆盖到的时间点)。但不幸的是,农夫约翰雇佣
了比它支付能力多出K个的救生员。他需要开除正好K个救生员,求出剩余的救生员最大能够覆盖多长的时间(一段
时间被覆盖当且仅当这时有至少一个救生员在工作)
Input
第一行包含N和K(K≤N≤10^5,1≤K≤100)
接下来的N行,每行描述一个在区间1…10^9上的救生员
给定这个救生员区间的开始和结束位置,其中有些救生员的区间可能会相交。
Output
请输出一个数字,表示如果农夫约翰开除K个救生员,剩余救生员最大能够覆盖的时间长度
Sample Input
3 2
1 8
7 15
2 14
Sample Output
12
农夫约翰应该开除掉覆盖1…8和7…15两个区间的两个救生员
HINT
Source
Platinum 鸣谢WenDavid提供翻译
首先贪心的把包含于其他线段的线段删除 然后按照左端点排序 那么显然右端点也是单调递增的
设dp[i][k]表示 前i条线段删除k条 i这条线段必须选的最大覆盖长度是多少
那么dp[i][k]=max{dp[j][k-(i-j-1)]};
那么显然可以知道我加入由dp[x][y]->dp[i][j] 那么显然我需要满足 x-y=i-j-1
那么如果i与j 不相交的时候 我可以储存我这个dp的最大值 然后直接加上len[i]即可 如果相交的话 我可以设dp[i][j]+line[i].r-line[x].l所以我针对我后面这个维护多个单调队列即可
然后最后统计答案的时候相当于 我枚举我最后一条边选取的是哪些边 这样的话恰好保证答案的不重不漏

#include<deque>
#include<queue>
#include<cstdio>
#include<algorithm>
#define pa pair<int,int>
#define N 100010
#define fi first
#define se second
using namespace std;
inline char gc(){static char now[1<<16],*S,*T;if (T==S){T=(S=now)+fread(now,1,1<<16,stdin);if (T==S) return EOF;}return *S++;
}
inline int read(){int x=0,f=1;char ch=gc();while(ch<'0'||ch>'9') {if(ch=='-') f=-1;ch=gc();}while(ch<='9'&&ch>='0') x=x*10+ch-'0',ch=gc();return x*f;
}
int dp[N][110],mx[N],n,k;
deque<pa> q[N];
struct node{int l,r;
}init[N],line[N];
inline bool cmp(const node &a,const node &b){return a.l==b.l?a.r<b.r:a.l<b.l;
}
int main(){//freopen("bzoj5185.in","r",stdin);n=read();k=read();int cnt=0;for (int i=1;i<=n;++i) init[i].l=read(),init[i].r=read();sort(init+1,init+n+1,cmp);int mxr=0; for (int i=1;i<=n;++i){if (init[i].r>mxr) line[++cnt]=init[i],mxr=init[i].r;else --k;}if (k<0) k=0;n=cnt;for (int i=1;i<=n;++i){for (int j=0;j<=k;++j){if (j>=i) break;int lt=i-j-1;while(!q[lt].empty()&&line[q[lt].front().fi].r<line[i].l) {int id=q[lt].front().fi;mx[lt]=max(mx[lt],dp[id][id-lt]);q[lt].pop_front();}dp[i][j]=max(dp[i][j],mx[lt]+line[i].r-line[i].l);if (!q[lt].empty()) dp[i][j]=max(dp[i][j],q[lt].front().se+line[i].r);lt=i-j;int tmp=dp[i][j]-line[i].r;while(!q[lt].empty()&&tmp>=q[lt].back().se) q[lt].pop_back();q[lt].push_back(make_pair(i,tmp));}}int ans=0;for (int i=1;i<=n;++i) if (k>=(n-i)) ans=max(ans,dp[i][k-(n-i)]);printf("%d\n",ans);return 0;
}

bzoj5185 [Usaco2018 Jan]Lifeguards相关推荐

  1. BZOJ5185: [Usaco2018 Jan]Lifeguards

    好吧,自己考虑的时候没想过要开多个单调队列来优化dp... 首先,如果一个区间被其他区间包含的话,很明显,它被删除也没影响.所以我们先按左节点排序,去除那些包含的区间,然后对接下来有序的区间进行dp. ...

  2. bzoj5185 [Usaco2018 Jan]Lifeguards(dp+单调队列优化)

    真是太神了orz 我们先贪心地把被包含的线段删掉,把剩下的线段按左端点排序,这样的话右端点显然也是有序的. 设dp[i][k],表示前i个线段,删了k个,且必须保留i线段的最大覆盖长度.枚举上一个线段 ...

  3. 单调队列优化dp--bzoj5185: [Usaco2018 Jan]Lifeguards

    传送门 luoguluoguluogu上据说有一道这个题的弱化版,把删kkk个改成了删111个,那个大概线段树之类的随便做一下就好了 这道题可以先把包含的都去掉,所有线段就是相交或者不相交的了,然后考 ...

  4. 退役前的做题记录1.0

    退役前的做题记录1.0 租酥雨最近很懒qwq,具体表现在写题的时候不想发题解了. 但是想想这样也不太好,就决定发个一句话(半句话到几句话不等)题解上来. 2018-09.18-2018-09.28 [ ...

  5. 1677: [Usaco2005 Jan]Sumsets 求和

    1677: [Usaco2005 Jan]Sumsets 求和 Time Limit: 5 Sec  Memory Limit: 64 MB Submit: 626  Solved: 348 [Sub ...

  6. bzoj2020[Usaco2010 Jan]Buying Feed, II*

    bzoj2020[Usaco2010 Jan]Buying Feed, II 题意: FJ开车去买食物,如果他的车上有X份食物.每走一里就花费X元. 城市总共E里路,FJ从0开始走,到E结束(不能往回 ...

  7. bzoj3396[Usaco2009 Jan]Total flow 水流*

    bzoj3396[Usaco2009 Jan]Total flow 水流 题意: 求无环图的最大流.边数≤700. 题解: 管它有没有环.注意本题的节点标号既有大写字母,也有小写字母. 代码: 1 # ...

  8. [BZOJ] 1634: [Usaco2007 Jan]Protecting the Flowers 护花

    1634: [Usaco2007 Jan]Protecting the Flowers 护花 Time Limit: 5 Sec  Memory Limit: 64 MB Submit: 827  S ...

  9. BZOJ 1612: [Usaco2008 Jan]Cow Contest奶牛的比赛【Floyd】

    1612: [Usaco2008 Jan]Cow Contest奶牛的比赛 Time Limit: 5 Sec Memory Limit: 64 MB Description FJ的N(1 <= ...

最新文章

  1. 独家 | 用spaCy蒸馏BERT模型
  2. AtCoder AGC002F Leftmost Ball (DP、组合计数)
  3. mfc存储颜色到mysql_mfc存储二进制文件
  4. kernel mtd 分区与UBOOT 分区的理解
  5. Linux cpu亲和力
  6. UVA1584 ​​​​​​​Circular Sequence【字符串】
  7. 详解Linux环境软RAID 5建立过程
  8. 设计一个基于GUI的扑克程序
  9. C# Explicit 和 Implicit
  10. FindWindowEx的应用
  11. 用代码来理解 C#委托与事件
  12. 计算机网络:四类数据编码技术
  13. 我的OpenBSD配置文件
  14. 将 打包为 物理机 虚拟机镜像_(完整版)十个步骤将操作系统从物理机迁移到虚拟机...
  15. 基于OpenCV的卡尔曼滤波的设计
  16. 华为有哪些高科技技术?
  17. python爬虫:爬去汽车之家
  18. 【贝叶斯神经网络训练】(torch实现)
  19. 【Python字符串】
  20. 基于JavaWeb的校园故障报修系统(源码+数据脚本+论文+技术文档)

热门文章

  1. C语言-统计单词个数
  2. 大部分有高学历的人比低学历的人强
  3. 面料ERP_面料企业ERP管理系统_面料软件
  4. 用html代码画玫瑰花
  5. 物理-光学仪器-三菱镜:三菱镜 百科
  6. 人才管理是什么意思_复合型人才是什么意思(复合型人才八种能力)
  7. AVD Android虚拟设备root教程
  8. ORACLE 按照指定的ID 顺序排序
  9. 赚想赚钱的人的钱最好赚了
  10. mfc 中文乱码转换为正常中文_MFC下遇到的字符集和中文乱码问题