题目链接:传送门

题目:

题目描述

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 ;
}

最新文章

  1. JavaScript(三) 正则表达式 以及实现的功能
  2. Codeforces Round #199 (Div. 2) E. Xenia and Tree
  3. C# ArrayList
  4. 【leetcode❤python】 190. Reverse Bits
  5. 网络编程(发送get和post请求到服务器端,并获取响应)
  6. HTTP - 条件请求
  7. vs2008 c++工程如何设置生成调试信息
  8. UNIX网络编程——客户/服务器心搏函数
  9. OLLVM特性、使用原理
  10. 循环更新sqlserver数据库表ID
  11. Vmware ESXi日志文件存放目录地址
  12. PowerDesigner 15进行逆向工程生成数据库图表时,注释的comment的生成,解决PowerDesigner逆向工程没有列注释
  13. php代码中pre的作用??
  14. 【JavaScript】脚本
  15. 52张扑克牌快速生成js
  16. 3dContactPointAnnotationTool开发日志(二)
  17. sql把varchar转化为int型
  18. gulp 流处理
  19. 线程--demo3
  20. Collections常用方法总结

热门文章

  1. chrome google mozilla firefox bookmarks import export
  2. u-boot的内存分布
  3. js MDN 查看
  4. bzoj1096
  5. jenkins+findbugs+checkstyle+PMD静态代码检查(二)
  6. asp.net MVC之AuthorizeAttribute浅析
  7. react与vue的对比
  8. (C/C++学习笔记) 三. 作用域和可见性
  9. 玩转X-CTR100 | STM32F4 l X-Assistant串口助手控制功能
  10. HihoCoder - 1483 区间最值