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 的区间,求这些区间和的最大值. 细节: 没有细节???感觉没有??? 分析: 听说有两种方法!!! 好吧实际上是等价的只是看 ...
随机推荐
- mybatis枚举自动转换(通用转换处理器实现)
https://blog.csdn.net/fighterandknight/article/details/51520595 https://blog.csdn.net/fighterandknig ...
- 内联函数inline的用法
一.什么是内联函数 在C语言中,如果一些函数被频繁调用,不断地有函数入栈,即函数栈,会造成栈空间或栈内存的大量消耗.为了解决这个问题,特别的引入了inline修饰符,表示为内联函数. 栈空间就是指放 ...
- 服务消费和负载(Feign)
Spring Cloud Feign Spring Cloud Feign是一套基于Netflix Feign实现的声明式服务调用客户端.它使得编写Web服务客户端变得更加简单.我们只需要通过创建接口 ...
- 每天CSS学习之border-collapse
border-collapse是CSS2的一个属性,其作用是折叠表格(table)的边框.collapse翻译过来又折叠的意思. border-collapse有三个值: collapse:将表格和单 ...
- javascript进阶笔记(1)
学习js已经有一段时间了,大大小小还是能够做出一些东西来.不过觉得可惜的是,还是对js本身这门语言不是很熟悉,总有一点雾里看花的感觉,看得见,但是看不清楚.最近发现有一本关于js的叫做<忍者秘籍 ...
- C语言转义字符'\'
body, table{font-family: 微软雅黑; font-size: 13.5pt} table{border-collapse: collapse; border: solid gra ...
- Linux3.10.0块IO子系统流程(2)-- 构造、排序、合并请求
Linux块设备可以分为三类.分别针对顺序访问物理设备.随机访问物理设备和逻辑设备(即“栈式设备”) 类型 make_request_fn request_fn 备注 SCSI 设备等 从bio构 ...
- web项目与jsp有关的三个jar的依赖
<!-- jsp --> <dependency> <groupId>javax.servlet</groupId> <artifactId> ...
- webpack进阶构建项目(一):1.理解webpack加载器
1.理解webpack加载器 webpack的设计理念,所有资源都是“模块”,webpack内部实现了一套资源加载机制,这与Requirejs.Sea.js.Browserify等实现有所不同. We ...
- LINQ(数据库操作增、删、改及并发管理)
本文将演示如何通过 Entity Framework 数据模型创建.修改.删除数据库记录. Customer cust = new Customer() { CustomerID = "LA ...