zoukankan      html  css  js  c++  java
  • 【lower_bound、upperbound讲解、二分查找、最长上升子序列(LIS)模版】

    二分

    二分算法模板

    int bsearch(int *a, int x, int y, int v)
    {
        int mid;
        while(x < y)
        {
            mid = (x + y) / 2;
            if(a[mid] == v)
                return mid;
            if(a[mid] > v)
                y = mid;
            else 
                x = mid + 1;
        }
        return -1;
    }
    

    注意此模板只适用于查找a中是否存在v,存在的话则返回其中一个符合条件的位置,并不一定只有那一个位置,这个视情况而定。

    lower_bound

    lower_bound()在一个区间内进行二分查找,返回第一个大于等于目标值的位置(地址)

    upper_bound

    upper_bound()与lower_bound()的主要区别在于前者返回第一个大于目标值的位置(地址)

    int lowerBound(int x){
        int l=1,r=n;
        while(l<=r){
            int mid=(l+r)>>1;
            if (x>g[mid]) l=mid+1;
            else r=mid-1;
        }
        return l;
    }
    int upperBound(int x){
        int l=1,r=n;
        while(l<=r){
            int mid=(l+r)>>1;
            if (x>=g[mid]) l=mid+1;
            else r=mid-1;
        }
        return l;
    }
    

    最长上升子序列LIS

    这里提供一组代码,它用于返回数组b中最长的上升子序列的长度

    int cal(int *b)
    {
        vector<int> s;
        for(int i = 0; i < n ;i++)
        {
            if(s.empty()) s.push_back(b[i]);
            else
            {
                vector<int>::iterator it = upper_bound(s.begin(), s.end(), b[i]);
                if(it == s.end()) s.push_back(b[i]);
                else
                    *it = b[i];
            }
        }
        return s.size();
    }
    

    对应题目:HDU-5532、HDU-6197

    **再介绍一个用dp求最长子序列长度的算法,对应紫书P274,状态方程为dp[i]=max ( dp[ i ], dp[ j ]+1 ) ( 0<=j< i, a[ j ] < a[ i ] ) **

    #include <bits/stdc++.h>
    using namespace std;
    const int MAXX=100000+5;
    const int INF=INT_MAX;
    
    int a[MAXX],dp[MAXX]; // a数组为数据,dp[i]表示以a[i]结尾的最长递增子序列长度
    
    int main()
    {
        int n;
        while(cin>>n)
        {
            for(int i=0; i<n; i++)
            {
                cin>>a[i];
                dp[i]=1; // 初始化为1,长度最短为自身
            }
            int ans=1;
            for(int i=1; i<n; i++)
            {
                for(int j=0; j<i; j++)
                {
                    if(a[i]>a[j])
                    {
                        dp[i]=max(dp[i],dp[j]+1);  // 状态转移
                    }
                }
                ans=max(ans,dp[i]);  // 比较每一个dp[i],最大值为答案
            }
            cout<<ans<<endl;
        }
        return 0;
    }
    
    

    参考博客:https://blog.csdn.net/wbin233/article/details/77570070

  • 相关阅读:
    程序员的四个阶段
    2010Year Plans
    HttpHandler HttpModule入门篇
    Lucene.net索引文件的并发访问和线程安全性
    stream流写到MemoryStream内存流引发得问题
    ASP.NET 2.0 多文件上传小经验
    HTML 迷魂灯
    如何在Windows下搭建Android开发环境
    利用Lucene.net搭建站内搜索(4)数据检索
    数据加密和解密
  • 原文地址:https://www.cnblogs.com/KeepZ/p/11285936.html
Copyright © 2011-2022 走看看