[JZOJ3233] 照片
题目
题目大意
有一个\(01\)序列。给你一堆区间,每个区间中有且仅有一个\(1\)点。
问最多的\(1\)点个数。
思考历程
感觉这题特别经典,似乎在哪里见过,又好像没有见过。
一开始朝贪心方面想……想不出来……
后来想DP,还是想不出来……
直到WHH大爷跑过来兴奋地说:不就是个差分约束吗!
于是我心态崩了,去搜题解……
然而搜到的全是DP……
理解了一下DP的方法,虽然理解,但是极度不熟练……
可是这题对代码能力的考验又很强……我本想自己打出极其恶心的方法,但后来还是仔细看了看题解(还有)标程。
几乎是对着标打出来了……
心态崩了……
正解
先说DP。
设\(f_i\)表示选\(i\)的最多的\(1\)点数目。
方程为\(f_i=\max f_j +1\)
现在问题是\(j\)的范围怎么求。
这就很考验人的分析能力了——从两个方面考虑:
- 唯一性:所有包括\(i\)的区间内都不能再选别的。这样可以求出右边界\(R_i\),为包含\(i\)的区间的最小左边界\(-1\)。
- 必要性:所有不包括\(i\)的区间(\(i\)之前的)中都必须要有一个选。这样可以求出右边界\(L_i\),为不包含\(i\)的区间的最大左边界
这样,求出\(L_i\)和\(R_i\),就可以转移了。
如果不刻意追求代码的完美,其实这个时候用线段树来辅助转移就好了,简单粗暴(如果是比赛,我肯定就这么打了)。
但是实际上可以优化。
首先可以证明出一个结论:\(L\)和\(R\)都是递增的。
如果\(L_{i-1}>L_i\),由于包含了\(i\)的区间也会包含\(i-1\)(除非区间左边界为\(i\),但显然这种情况下\(L{i-1}\leq L_i\)),\(L_{i-1}\)为包含\(i-1\)区间的最小左边界\(-1\),所以\(L_{i-1}\)可以被更新,所以不成立。
如果\(R_{i-1}>R_i\),由于不包含\(i-1\)的区间也不包含\(i\),\(R_i\)为不包含\(i\)区间的最大右边界,所以\(R_i\)可以被更新,所以不成立。
既然都是递增的,那就可以很愉快地单调队列DP了……
有了各种单调的性质,代码也可以简单很多,也不需要打线段树或堆了……
然而……如果是在比赛,想这些的时间还不如用来打线段树呢……
还有一种方法是差分约束。
假如我们做一遍前缀和,对于区间\([l,r]\),就会有\(s_l+1=s_r\),相当于\(s_l+1\geq s_r\)且\(s_r-1\geq s_l\)。还有,将每个左右端点排个序记为\(x_i\),那么还有\(x_{i-1}\leq x_i\)
差分约束即可……当然我没有打过,所以纯属瞎哔哔……
代码
using namespace std;
#include <cstdio>
#include <cstring>
#include <algorithm>
#define N 200010
int n,m;
struct Section{
int l,r;
} s[N];
inline bool cmps(const Section &a,const Section &b){
return a.l<b.l || a.l==b.l && a.r<b.r;
}
int L[N],R[N];
int q[N],head,tail;
int f[N];
int main(){
scanf("%d%d",&n,&m);
for (int i=1;i<=n+1;++i)
R[i]=i-1;
for (int i=1;i<=m;++i){
scanf("%d%d",&s[i].l,&s[i].r);
L[s[i].r+1]=max(L[s[i].r+1],s[i].l);
R[s[i].r]=min(R[s[i].r],s[i].l-1);
}
for (int i=n;i>=1;--i)
R[i]=min(R[i],R[i+1]);
for (int i=2;i<=n+1;++i)
L[i]=max(L[i],L[i-1]);
memset(f,127,sizeof f);
f[0]=0;
for (int i=1,j=0;i<=n+1;++i){
for (;j<=R[i];++j){
if (f[j]==0x7f7f7f7f)
continue;
while (head<=tail && f[q[tail]]<f[j])
tail--;
q[++tail]=j;
}
while (head<=tail && q[head]<L[i])
head++;
if (head<=tail)
f[i]=f[q[head]]+1;
}
if (f[n+1]==0x7f7f7f7f)
printf("-1\n");
else
printf("%d\n",f[n+1]-1);
return 0;
}
总结
真是一道单调队列的好题。
当然,如果是比赛,我肯定会选择打线段树的。
[JZOJ3233] 照片的更多相关文章
- Photoshop将普通照片快速制作二次元漫画风格效果
今天为大家分享Photoshop将普通照片快速制作二次元漫画风格效果,教程很不错,对于喜欢漫画的朋友可以参考本文,希望能对大家有所帮助! 一提到日本动画电影,大家第一印象肯定是宫崎骏,但是日本除了宫崎 ...
- mono for android 获取手机照片或拍照并裁剪保存
axml <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android ...
- 计算照片的面积(WPF篇)
昨天,老周突发其想地给大伙伴们说了一下UWP应用中计算照片面积的玩法,而且老周也表示会提供WPF版本的示例.所以,今天就给大伙们补上吧. WPF是集成在.net框架中,属于.net的一部分,千万不要跟 ...
- 计算照片的面积(UWP篇)
今天先说UWP应用程序上计算照片面积的方法,改天有空,再说说WPF篇. 其实计算照片面积的原理真TMD简单,只要你有本事读到照片的像素高度和宽度,以及水平/垂直方向上的分辨率(DPI)就可以了.计算方 ...
- 部分Android手机拍照后照片被旋转的解决方案
在部分Android手机(如MT788.Note2)上,使用Camera拍照以后,得到的照片会被自动旋转(90°.180°.270°),这个情况很不符合预期.仔细分析了一下,因为照片属性中是存储了 ...
- Win10系统怎样让打开图片方式为照片查看器
转载自:百度经验 http://jingyan.baidu.com/article/5d368d1ef0cad13f60c057e3.html 1.首先,我们需要使用注册表编辑器来开启Win10系统照 ...
- Smart3D系列教程4之 《案例实战演练1——小物件的照片三维重建》
一.前言 Wish3D出品的Smart3D系列教程已经推出3讲了,分别是关于倾斜摄影三维建模原理应用.照片采集技巧.Smart3D各个功能模块的作用,它们都是围绕Smart3D建模软件进行的讲解.那么 ...
- Smart3D系列教程3之 《论照片三维重建中Smart3D几个工作模块的功能意义》
[摘要] 近年来,倾斜摄影测量技术是国际测绘遥感领域近年发展起来的一项高新技术,利用照片进行三维重建成为一项关键性的技术.Smart3D软件,是照片三维重建主流软件之一,本文将就Smart3D建模软件 ...
- Hawk: 无编程抓取淘女郎的所有高清照片
1.这是什么鬼? 哦?美女? 最近看了这一篇文章:http://cuiqingcai.com/1001.html 大概说的是用Python和Pyspider(这货好像是我的一位师兄写的,吓尿),抓取淘 ...
随机推荐
- springcloud中config启动时候报错Caused by: java.lang.IllegalArgumentException: Could not resolve placeholder 'config.info' in value "${config.info}"
-noverify -Dspring.output.ansi.enabled=always -Dcom.sun.management.jmxremote -Dcom.sun.management.jm ...
- String,StringBuffer,StringBuilder
String是字符串常量:StringBuffer,StringBuilder是字符串变量 StringBuffer是线程安全的且效率低:StringBuilder是线程不安全的故效率高 操作少量字符 ...
- vue中ref的使用(this.$refs获取为undefined)
如果你获取到的总是空的,你注意一下: 1.你在哪里调用,和你调用的对象 试试在mounted()里面调用有效果没有 调用的对象是本来就存在的,还是需要数据渲染之后才会出现的,同理,在mounted() ...
- webpack4.x的使用历程
第一次接触的webpack是在一个3.x的资料中 在4.x的运用中遇到了好多的坑,我就以小白的身份把我使用webpaxk的过程分享出来,其中很多不足欢迎大佬们指正 node安装不再赘述 一.安装 np ...
- LoadRunner模拟REST接口的json请求
LoadRunner模拟REST接口的json请求 现在很多手机应用的性能测试,REST接口调用通过json格式,在用loadrunner模拟这些json请求时,需要开发提供 1.供接口地址 2.提交 ...
- 原生js如何获取某一元素的高度
三种方法: 1.document.getElementById("id").style.height,这种方法的前提是必须之前已经显示的在css中声明过height,才能取得正确的 ...
- [JZOJ6355] 【NOIP2019模拟】普 24/100
题目 题目大意 给你一个序列,对于所有\(k\in [1,n]\),求长度为\(k\)的子序列的最大权值,权值为\(a_1-a_2+a_3-...\pm a_k\) 思考历程 这题显然可以背包对吧-- ...
- ul -- li 模拟select下拉框
在写项目中 用到下拉框,一般用 <select name="" id=""> <option value=</option> &l ...
- JUC 一 线程池
线程 线程,是程序执行的最小单元.线程是进程中的其中一个实体,是被系统独立调度和分派的基本单位 它可与同属一个进程的其它线程共享进程所拥有的全部资源. 一个线程可以创建和撤消另一个线程,同一进程中的多 ...
- Django -- 分页 -- 批量导入
Django -- 分页 分页 Django提供了一些类实现管理数据分页,这些类位于django/core/paginator.py中 Paginator对象 Paginator(列表,int):返 ...