P3084 [USACO13OPEN]照片Photo (dp+单调队列优化)
题目链接:传送门
题目:
题目描述 Farmer John has decided to assemble a panoramic photo of a lineup of his N cows ( <= N <= ,), which, as always, are conveniently numbered from ..N. Accordingly, he snapped M ( <= M <= ,) photos, each covering a contiguous range of cows: photo i contains cows a_i through b_i inclusive. The photos collectively may not necessarily cover every single cow. After taking his photos, FJ notices a very interesting phenomenon: each photo he took contains exactly one cow with spots! FJ was aware that he had some number of spotted cows in his herd, but he had never actually counted them. Based on his photos, please determine the maximum possible number of spotted cows that could exist in his herd. Output - if there is no possible assignment of spots to cows consistent with FJ's photographic results. 输入输出格式
输入格式: * Line : Two integers N and M. * Lines ..M+: Line i+ contains a_i and b_i. 输出格式: * Line : The maximum possible number of spotted cows on FJ's farm, or -1 if there is no possible solution. 输入输出样例
输入样例#: 输出样例#: 说明 There are cows and photos. The first photo contains cows through , etc. From the last photo, we know that either cow or cow must be spotted. By choosing either of these, we satisfy the first two photos as well.
思路:
如果要把牛放在第i个位置,它之前的那只牛应该放在[li, ri]之间,根据输入处理出li和ri,就可以转移状态了。
读入x,y时,用x更新ly+1,用x-1更新ry。
读入结束之后从前往后扫一遍,用li-1更新li;再从后往前扫一遍,用ri+1更新ri。
然后就可以跑dp了,f[i] = max{f[j] | li ≤ j ≤ ri}
状态:
f[i] 表示把最后一只牛放在第i个位置的最大数量。
状态转移方程:
f[i] = max{f[j] | li ≤ j ≤ ri}
#include <bits/stdc++.h> using namespace std;
const int MAX_N = 2e5 + ;
#define tomax(a, b) a = a>b?a:b
#define tomin(a, b) a = a<b?a:b int N, M, l[MAX_N], r[MAX_N];
int f[MAX_N]; int main()
{
// freopen("testdata.in", "r", stdin);
cin >> N >> M;
for (int i = ; i <= N+; i++)
r[i] = i-;
for (int i = ; i <= M; i++) {
int x, y;
scanf("%d%d", &x, &y);
tomin(r[y], x-);
tomax(l[y+], x);
}
for (int i = ; i <= N+; i++)
tomax(l[i], l[i-]);
for (int i = N; i >= ; i--)
tomin(r[i], r[i+]);
memset(f, -, sizeof f);
f[] = ;
for (int i = ; i <= N+; i++)
for (int j = l[i]; j <= r[i]; j++) if(f[j] != -)
tomax(f[i], f[j] + (i!=N+ ? : )); cout << f[N+] << endl;
return ;
}
/*
5 3
1 4
2 4
1 1
*/
本来是瞄了一眼题解,理解了思路之后准备不优化暴力T一发的,结果直接AC了,还跑得贼快?-。=
不过这样子写应该可以被两只牛的大数据卡掉:
献上单调队列优化的正解:
#include <bits/stdc++.h> using namespace std;
const int MAX_N = 2e5 + ;
#define tomax(a, b) a = a>b?a:b
#define tomin(a, b) a = a<b?a:b int N, M, l[MAX_N], r[MAX_N];
int h, t, q[MAX_N], f[MAX_N]; int main()
{
cin >> N >> M;
memset(f, , sizeof f);
for (int i = ; i <= N+; i++)
r[i] = i-;
for (int i = ; i <= M; i++) {
int x, y;
scanf("%d%d", &x, &y);
tomin(r[y], x-);
tomax(l[y+], x);
}
for (int i = ; i <= N+; i++)
tomax(l[i], l[i-]);
for (int i = N; i >= ; i--)
tomin(r[i], r[i+]);
int j = ;
h = , t = , q[++t] = ;
for (int i = ; i <= N+; i++) {
while (j <= N && j <= r[i]) {
if (f[j] == -) {
++j;
continue;
}
while (h <= t && f[q[t]] <= f[j]) --t;
q[++t] = j;
++j;
}
while (h <= t && q[h] < l[i]) ++h;
if (h <= t) f[i] = f[q[h]] + (i!=N+ ? : );
else f[i] = -;
}
cout << f[N+] << endl;
return ;
}
P3084 [USACO13OPEN]照片Photo (dp+单调队列优化)的更多相关文章
- P3084 [USACO13OPEN]照片Photo dp
题意: 有n个区间,每个区间只能有一个斑点奶牛,问最多有几个斑点奶牛. 思路: 首先要处理出每个点的L[i],R[i]. L[i]表示L[i]-i-1之间一定有一个点.i也是选中的. R[i]表示R[ ...
- [poj3017] Cut the Sequence (DP + 单调队列优化 + 平衡树优化)
DP + 单调队列优化 + 平衡树 好题 Description Given an integer sequence { an } of length N, you are to cut the se ...
- 洛谷 P3084 [USACO13OPEN]照片Photo 解题报告
[USACO13OPEN]照片Photo 题目描述 农夫约翰决定给站在一条线上的\(N(1 \le N \le 200,000)\)头奶牛制作一张全家福照片,\(N\)头奶牛编号\(1\)到\(N\) ...
- 1023: [SHOI2008]cactus仙人掌图(DP+单调队列优化)
这道题吗= =首先解决了我多年以来对仙人掌图的疑问,原来这种高大上的东西原来是这个啊= = 然后,看到这种题,首先必须的就是缩点= = 缩点完之后呢,变成在树上找最长路了= =直接树形dp了 那么那些 ...
- Codeforces 1077F2 Pictures with Kittens (hard version)(DP+单调队列优化)
题目链接:Pictures with Kittens (hard version) 题意:给定n长度的数字序列ai,求从中选出x个满足任意k长度区间都至少有一个被选到的最大和. 题解:数据量5000, ...
- Codeforces 445A Boredom(DP+单调队列优化)
题目链接:http://codeforces.com/problemset/problem/455/A 题目大意:有n个数,每次可以选择删除一个值为x的数,然后值为x-1,x+1的数也都会被删除,你可 ...
- bzoj 1855 dp + 单调队列优化
思路:很容易写出dp方程,很容易看出能用单调队列优化.. #include<bits/stdc++.h> #define LL long long #define fi first #de ...
- 股票交易(DP+单调队列优化)
题目描述 最近lxhgww又迷上了投资股票,通过一段时间的观察和学习,他总结出了股票行情的一些规律. 通过一段时间的观察,lxhgww预测到了未来T天内某只股票的走势,第i天的股票买入价为每股APi, ...
- Luogu 2627 修建草坪 (动态规划Dp + 单调队列优化)
题意: 已知一个序列 { a [ i ] } ,求取出从中若干不大于 KK 的区间,求这些区间和的最大值. 细节: 没有细节???感觉没有??? 分析: 听说有两种方法!!! 好吧实际上是等价的只是看 ...
随机推荐
- wps去除首字母自动大写
首字母大写功能在不是进行英文编写时是个“自作聪明”的功能,我们可能会想把它关掉.
- vs2015 出现Lc.exe 已退出,代码为-1的问题,如何解决
今天在代码运行时,出现lc.exe已退出,代码为-1 的问题
- shell 键盘输入
命令:read 从键盘读入数据,赋值变量 [root@ssgao shell]# cat b.sh #!bin/bash read a b c echo "a is : ${a}" ...
- 深入理解 Java 虚拟机——走近 Java
1.1 - 概述 Java 总述:Java 不仅是一门编程语言,还是一个由一系列 计算机软件 和 规范 形成的技术体系,这个技术体系提供了完整的用于软件开发和跨平台部署的支持环境,并广泛应用于 嵌入式 ...
- day01 初识Python
今日主要内容 1.初识python 2.简单了解下python的数据类型 nubmer=int(input("请输入数字大小:")) if nubmer>66: print( ...
- core1.1 升级到 2.0
1.直接修改项目 1.1 改成 2.0 Startup 的修改 去除构造函数中下面的代码 var builder = new ConfigurationBuilder() .SetBasePath(e ...
- centos installation of matlab R2015b
the source of installation is in the website: http://blog.csdn.net/hejunqing14/article/details/50265 ...
- merge into用法小结
CREATE OR REPLACE PROCEDURE PRO_ZXC(O_NO OUT NUMBER,O_NOTE OUT NUMBER)ASBEGIN O_NO:=1; MERGE INTO QQ ...
- Vuejs2.0学习(Render函数,createElement,vm.$slots)
直接来到进阶部分, Render函数 直接来到Render,本来也想跳过,发现后面的路由貌似跟它还有点关联.先来看看Render 1.1 官网一开始就看的挺懵的,不知道讲的是啥,动手试了一下,一开头讲 ...
- 编程实现Linux系统的od功能
选做题目以及分析 题目:编写MyOD.java 用java MyOD XXX实现Linux下od -tx -tc XXX的功能 分析:我觉得这道题目中的参数应当是-tx1而不是-tx,使用了-tx后结 ...