8593 最大覆盖问题 two pointer

8593 最大覆盖问题

时间限制:50MS  内存限制:1000K
提交次数:193 通过次数:88

题型: 编程题   语言: G++;GCC;VC

Description

输入格式

第1行是正整数n,(n<=10000)
第2行是整数序列 a1   a2   ...   an

输出格式

计算出的最大覆盖区间长度

输入样例

10
1 6 2 1 -2 3 5 2 -4 3

输出样例

5

提示

若依次去求出每个数的最大覆盖长度,则必须有两个嵌套的循环,时间复杂度为O(n^2)。
但此处求所有数的一个最大覆盖长度,倒没有必要每个数的最大覆盖长度都求出来。

初始时,用两个指针i和j指向串末,当ai和aj的关系满足不等式时,j不动,i往左
走,……,直到不等式不满足,记录下长度。
下一步j往左移一个,i不回退,继续上面的比较,若找到更长的覆盖长度,更新。
每循环一次要么i要么j少1;最后i=-1,j=0;共进行了2(n-1)次。所以时间复杂度为O(n)。

我的思路是dp。dp[i]表示以第i个为结尾的最大覆盖长度。然后枚举第i + 1个时,如果其abs还比a[i]小,那么dp[i + 1] = 1,就是自己一个了。否则,因为它比a[i]大了,而a[i]之前也算好了dp[i],就是[i - dp[i] + 1, dp[i] ]这段区间是比abs(a[i])小的了,所以可以不比较这段区间,直接和i - dp[i]比较即可。然后递归下去。

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm>
#define IOS ios::sync_with_stdio(false)
using namespace std;
#define inf (0x3f3f3f3f)
typedef long long int LL;

#include <iostream>
#include <sstream>
#include <vector>
#include <set>
#include <map>
#include <queue>
#include <string>
const int maxn = 10000 + 20;
int a[maxn];
int dp[maxn];
void work() {
    int n;
    scanf("%d", &n);
    for (int i = 1; i <= n; ++i) {
        scanf("%d", &a[i]);
    }
    a[0] = inf;
    dp[1] = 1;
    for (int i = 2; i <= n; ++i) {
        int t = abs(a[i]);
        if (t < a[i - 1]) {
            dp[i] = 1;
        } else {
            int pos = i - 1 - dp[i - 1];
            while (t >= a[pos]) {
                pos = pos - dp[pos];
            }
            dp[i] = i - pos;
        }
    }
    int ans = 0;
    for (int i = 1; i <= n; ++i) {
        ans = max(ans, dp[i]);
    }
    printf("%d\n", ans);
}
int main() {
#ifdef local
    freopen("data.txt","r",stdin);
#endif
    work();
    return 0;
}

题解是用了two pointer

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm>
#define IOS ios::sync_with_stdio(false)
using namespace std;
#define inf (0x3f3f3f3f)
typedef long long int LL;

#include <iostream>
#include <sstream>
#include <vector>
#include <set>
#include <map>
#include <queue>
#include <string>
const int maxn = 10000 + 20;
int a[maxn];
int dp[maxn];
void work() {
    int n;
    scanf("%d", &n);
    for (int i = 1; i <= n; ++i) {
        scanf("%d", &a[i]);
    }
    int ans = 0;
    int R = n, L = n;
    while (L >= 1) {
        while (L >= 1 && a[L] <= abs(a[R])) {
            --L;
        }
        ans = max(ans, R - L);
        R--;
    }
    printf("%d\n", ans);
}
int main() {
#ifdef local
    freopen("data.txt","r",stdin);
#endif
    work();
    return 0;
}

				
时间: 2024-11-07 13:27:39

8593 最大覆盖问题 two pointer的相关文章

JQUERY 拖拽 draggable droppable resizable selectable sortable

今天用了jq ui的拖动碰撞功能,好不容易看到有详细的API解说,记录如下: <script language="JavaScript" type="text/javascript" src="ui/jquery-1.8.2.js"></script> <script language="JavaScript" type="text/javascript" src="

JQuery UI - selectable

·概述 Selectable插件允许用户对指定的元素进行选中的动作.此外还支持按住Ctrl键单击或拖拽选择多个元素. 官方示例地址:http://jqueryui.com/demos/selectable/ ·参数(参数名 : 参数类型 : 默认值) autoRefresh : Boolean : true 决定是否在每次选择动作时,都重新计算每个选中元素的坐标和大小.如果你有很多个选择项的话,建议设置成false并通过方法手动刷新. 初始:$('.selector').selectable({

jQuery UI draggable+droppable+resizable+selectable+sortable

<script language="JavaScript" type="text/javascript" src="ui/jquery-1.8.2.js"></script> <script language="JavaScript" type="text/javascript" src="ui/jquery-ui-1.9.1.custom.js">&

jQuery UI-Draggable 参数集合

·概述    在任何DOM元素启用拖动功能.通过单击鼠标并拖动对象在窗口内的任何地方移动.    官方示例地址:http://jqueryui.com/demos/draggable/      所有的事件回调函数都有两个参数:event和ui,浏览器自有event对象,和经过封装的ui对象    ui.helper - 表示被拖拽的元素的JQuery对象    ui.position - 表示相对当前对象,鼠标的坐标值对象{top,left}    ui.offset - 表示相对于当前页面,

C++中Reference与指针(Pointer)的使用对比

我们已经知道在C++中,对象变量直接存储的是对象的值.这是与Java不同的,在Java中对象变量存储的是一个地址,该地址指向对象值实际存储的地方.有时在C++中也需要实现这样的布置,这就用到了指针pointer.在 C++中,一个指向对象的变量叫做指针.如果T是一种数据类型,则 T* 是指向这种数据类型的指针. 这里重点介绍C++与Java的不同,要详细了解C++中指针的使用 就像 Java中一样,一个指针变量可以被初始化为空值 NULL,另外一个指针变量的值,或者一个调用new生成的新对象:

C++ 成员函数的重载与覆盖与隐藏

重载与覆盖 成员函数被重载的特征: (1)相同的范围(在同一个类中): (2)函数名字相同: (3)参数不同: (4)virtual 关键字可有可无. 覆盖是指派生类函数覆盖基类函数,特征是: (1)不同的范围(分别位于派生类与基类): (2)函数名字相同: (3)参数相同: (4)基类函数必须有 virtual 关键字. 函数 Base::f(int)与 Base::f(float)相互重载,而 Base::g(void) 被 Derived::g(void)覆盖. #include <ios

C++中重载、覆盖与隐藏的区别(转)

本文摘自林锐博士的<高质量C++/C编程指南>. 成员函数的重载.覆盖(override)与隐藏很容易混淆,C++程序员必须要搞清楚概念,否则错误将防不胜防. 1. 重载与覆盖 成员函数被重载的特征: (1)相同的范围(在同一个类中): (2)函数名字相同: (3)参数不同: (4)virtual关键字可有可无. 覆盖是指派生类函数覆盖基类函数,特征是: (1)不同的范围(分别位于派生类与基类): (2)函数名字相同: (3)参数相同: (4)基类函数必须有virtual关键字. 在下例中,函

覆盖与重载与隐藏——SAP电面(3)

参考:http://man.chinaunix.net/develop/c&c++/c/c.htm#_Toc520634042 8.2.1 重载与覆盖 成员函数被重载的特征: (1)相同的范围(在同一个类中): (2)函数名字相同: (3)参数不同: (4)virtual关键字可有可无. 覆盖是指派生类函数覆盖基类函数,特征是: (1)不同的范围(分别位于派生类与基类): (2)函数名字相同: (3)参数相同: (4)基类函数必须有virtual关键字. 示例8-2-1中,函数Base::f(i

C++中成员函数的重载、覆盖和隐藏的区别

转载请注明,原创地址:点击打开链接   http://blog.csdn.net/u010587274/article/details/38928561 个人微信公众号:tanzi_888 (潭子技术圈) C++中成员函数的重载.覆盖和隐藏的区别: 1 重载(overload): 是函数名相同,参数列表不同 重载只是在类的内部存在.但是不能靠返回值类型来判断.1.1)相同的范围(在同一个类中)1.2)函数名字相同1.3)参数不同 1.4)Virtual关键字可有可无 2  覆盖 (overrid