`
huyifan951124
  • 浏览: 82765 次
社区版块
存档分类
最新评论

hdu5532 最长不上升子序列+最长不下降子序列

 
阅读更多

题目大意:让你求出这个串是否是近似有序串,什么叫做近似有序串呢,就是,这个串去掉任意一个字符也能保持有序。

算法思路:模板题,只需要求出最大的有序子串,然后看这个串总的长度-1是否小于等于最大有序子串的长度,如果不满足,则说明这个串不是近似串。如何求最大有序子串呢,就比较一下最长不上升子序列的长度和最长不下降子序列的长度,取最长的即可。

#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
#define MAXN 100050
#define INF 0x3f3f3f3f
int t,a[MAXN],ans[MAXN],d[MAXN],S[MAXN],n;

int BSearch(int x, int y, int v) //二分求上界(不上升)
{
    while(x <= y)
    {
        int mid = x+(y-x)/2;
        if(S[mid] >= v) x = mid+1;
        else y = mid-1;
    }
    return x;
}
int BSearch2(int x, int y, int v) //二分求上界(不下降)
{
    while(x <= y)
    {
        int mid = x+(y-x)/2;
        if(S[mid] <= v) x = mid+1;
        else y = mid-1;
    }
    return x;
}

int LIS()//最长不下降子序列
{
    memset(d,0,sizeof(d));
    for(int i = 1; i <=n; i++) S[i] = INF;
    int res = 0;
   for(int i = 1; i <= n; i++)
    {
        int x = 1, y = i;
        int pos = BSearch2(x, y, a[i]);
        d[i] = pos;
        S[d[i]] = min(S[d[i]], a[i]);
        res = max(res, d[i]);
    }
    return res;
}
int LFS()//最长不上升子序列
{
     for(int i = 1; i <=n; i++) S[i] = -INF; //注意初始值
    memset(d, 0, sizeof(d));
    int res = 0;
    for(int i = 1; i <= n; i++)
    {
        int x = 1, y = i;
        int pos = BSearch(x, y, a[i]);
        d[i] = pos;
        S[d[i]] = max(S[d[i]], a[i]);
       res = max(res, d[i]);
    }
    return res;
}
int main()
{

    scanf("%d",&t);
    while(t--)
    {
        scanf("%d",&n);

        for(int i=1; i<=n; i++)
        {
            scanf("%d",&a[i]);
        }

        int len1=LIS();//nlogn
        int len2=LFS();//nlogn

        int flag=max(len1,len2);

        if(n-1<=flag)
        {
            printf("YES\n");
        }
        else
        {
            printf("NO\n");
        }


    }



    return 0;

}

 这里顺便补充一下,最长上升子序列和最长下降子序列的模板,过几天就去比赛了,记录一下。

#include<cstdio>
#include<cstring>
#define MAXN 40005

int arr[MAXN],ans[MAXN],len;



int binary_search(int i)
{
    int left,right,mid;
    left=0,right=len;
    while(left<right)
    {
        mid = left+(right-left)/2;
        if(ans[mid]>=arr[i]) right=mid;
        else left=mid+1;
    }
    return left;
}

int main()
{
   
    int T,p,i,j,k;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d",&p);
        for(i=1; i<=p; ++i)
            scanf("%d",&arr[i]);

        ans[1] = arr[1];
        len=1;
        for(i=2; i<=p; ++i)
        {
            if(arr[i]<ans[len]) //这个是求最长上升子序列,如果是求下降的话,改成小于号即可
                ans[++len]=arr[i];
            else
            {
                int pos=binary_search(i);   
                ans[pos] = arr[i];
            }

        }
        printf("%d\n",len);
    }

    return 0;

}

 

0
0
分享到:
评论

相关推荐

    hdu 1257 最低拦截系统 lis

    题目名为“hdu 1257 最低拦截系统”,这里的“最低拦截系统”实际上是描述了一个问题场景,而具体的问题通过描述部分可以得知是要求找出给定数组中的最长递增子序列的长度。这里所谓的“最低拦截系统”可能是为了...

    HDU+2000-2099+解题报告

    例如背包问题、最长公共子序列、矩阵链乘法等。 3. **图论**:包括最短路径算法(Dijkstra、Floyd-Warshall、Bellman-Ford)、最小生成树(Prim、Kruskal)、拓扑排序等。 4. **字符串处理**:如KMP算法、Manacher...

    HDU+2000-2099+解题报告.zip

    1. **动态规划**:动态规划是一种用于解决最优化问题的常用方法,例如背包问题、最长公共子序列、矩阵链乘法等。解题报告会解释如何定义状态、设计状态转移方程,并给出具体代码实现。 2. **图论算法**:包括最短...

    hdu 300+ AC 代码

    在编程竞赛中,动态规划常用于解决背包问题、最长公共子序列、最短路径等问题。理解动态规划的状态转移方程和边界条件是掌握这一方法的关键。 这个压缩包中的300+ AC代码提供了丰富的示例,可以帮助学习者深入理解...

    ACM HDU题目分类

    1025 经典 DP,最长递增子序列(要用 NLogN 的方法过);1051 经典贪心,也可以用 DP;1058 经典问题,丑数,DP;1081 经典 DP 等等。 搜索题 搜索题是 ACM HDU 题目分类中的一大类,例如,1010 搜索题,剪枝很...

    HDU DP动态规划

    常见的DP题目类型包括但不限于最长公共子序列、背包问题、最短路径、区间调度等。 在动态规划中,我们通常遵循以下步骤: 1. **定义状态**:确定问题的状态,通常是问题的关键属性的组合。 2. **状态转移方程**:找...

    HDU题目java实现

    9. **动态规划**:这是一种优化策略,通过构建状态转移方程来求解问题,例如背包问题、最长公共子序列、矩阵链乘法等。 10. **回溯法**:在解决组合优化问题和逻辑推理问题时常用,如八皇后问题、数独求解等。 11....

    ACM HDU

    2. **动态规划**:解决许多具有重叠子问题和最优子结构的问题,如背包问题、最长公共子序列等。 3. **贪心算法**:在每一步选择局部最优解,以期达到全局最优,如活动安排问题、霍夫曼编码等。 4. **数据结构**:...

    hdu acm 教案(3)

    动态规划适用于有重叠子问题和最优子结构的问题,例如背包问题、最长公共子序列、斐波那契数列等。 在"动态规划(1)"的课程中,可能会讲解以下几个关键知识点: 1. **基本概念**:首先,会介绍动态规划的基本定义,...

    基础动态规划及排序代码

    3. **不连续公共子序列**:在`不连续公共子序列.cpp`中,这是寻找两个字符串之间最长的不连续公共子序列的问题。动态规划在这里通过构建一个二维状态转移矩阵来解决,每个单元格表示对应位置的两个字符是否匹配及其...

    hdu动态规划算法集锦

    - 定义状态$sum[j]$表示到第$j$个位置为止的最长跳跃序列长度。 - 状态转移方程:$sum[j] = \max\{sum[i]\} + 1$,其中$0 \le i $,并且$a[i] [j]$。 #### MonkeyAndBanana 题目链接:[MonkeyAndBanana]...

    ACM-HDU涉及了很多算法

    典型问题如背包问题、最长公共子序列、矩阵链乘法等。 7. **贪心算法**:贪心算法在每一步选择局部最优解,期望最终得到全局最优解。它常用于解决资源分配、任务调度等问题,如霍夫曼编码、Prim算法的贪心版本等。 ...

    HDU-ACM课件.rar

    经典的DP问题包括最长公共子序列、最短路径问题(如Floyd-Warshall算法)、背包问题等。 8. **并查集**:并查集是一种用于处理集合合并和查询是否属于同一集合的数据结构。在图论中,它可以用来判断两个节点是否...

    HDU算法讲解的PPT

    3. **动态规划**:这是解决最优化问题的重要方法,例如背包问题、最长公共子序列、矩阵链乘法等。动态规划强调状态转移方程和最优子结构,理解这些原理有助于解决各种复杂问题。 4. **字符串算法**:如KMP匹配、...

    hdu acm教案3

    此外,教程还提出了一个思考题——最长有序子序列I,展示了如何使用动态规划找到一个序列中的最长递增子序列。在动态规划解决方案中,我们可以维护一个F数组,其中F[I]表示以I结尾的最长递增子序列的长度。 最后,...

    hdu ACM代码 每种算法都有分类

    3. **动态规划**:动态规划是ACM中非常关键的一部分,它能解决很多优化问题,如背包问题、最长公共子序列、矩阵链乘法等。动态规划的核心是状态转移方程和优化存储结构。 4. **数学算法**:包括数论(模运算、同余...

    HDU-2000-2099.rar_hdu

    3. **动态规划**:2051-2100号题目可能包含动态规划思想的应用,如背包问题、最长公共子序列、最短路径等。动态规划是一种通过将大问题分解为小问题来求解的方法,适合解决具有重叠子问题和最优子结构的问题。 4. *...

    HDU题目分类

    - **1003**:这道题目可能涉及到基本的动态规划问题,比如背包问题或最长递增子序列等。 - **1024**:这可能是更复杂的动态规划题目,例如涉及到多个维度的状态转移。 - **1025**:这道题可能涉及到动态规划中的高级...

    HDU-2000-2099.zip_hdu2000

    3. **动态规划**:解决最优子结构和重叠子问题的问题,例如背包问题、最长公共子序列、矩阵链乘法等。 4. **贪心算法**:在每一步选择局部最优解,最终达到全局最优,如活动安排、霍夫曼编码等。 5. **回溯法**:...

    ACM hdu 代码大全3000例

    3. **动态规划**:动态规划是解决多阶段决策问题的有效方法,例如背包问题、最长公共子序列、最短路径等。如“HDU4000.cpp”可能包含了一个典型的动态规划问题的解法。 4. **图论**:图论问题包括最小生成树...

Global site tag (gtag.js) - Google Analytics