• POJ


    题意:
    求所给出长度为 N 的最长上升子序列长度
    ""思路:**
    (1) (O(n^2))的 动态转移:
    (dp[i])表示以(i)结尾的最长单调子序列,那么当(arr[i]>arr[j]时) (dp[i]=max(dp[j]+1,dp[i]) (jin[1,i)))

    #include <bits/stdc++.h>
    #define IOS ios::sync_with_stdio(0); cin.tie(0);
    #define accept 0
    #define mp make_pair
    using namespace std;
    typedef long long ll;
    typedef unsigned long long ull;
    typedef pair<int, int> pii;
    const int inf = 0x3f3f3f3f;
    const int maxn = 1e3+7;
    const int maxm = 1e6+7;
    const int mod = 1e9+7;
    
    int dp[maxn];
    int arr[maxn];
    int main(){
        int n;
        while(~scanf("%d",&n)){
            for(int i=1;i<=n;i++){
                scanf("%d",&arr[i]);
            	dp[i]  = 1;
    		}
        	
            int ans = -1;
            for(int i=1;i<=n;i++){
                for(int j=1;j<i;j++){
                    if(arr[i]>arr[j]) dp[i] = max(dp[j]+1,dp[i]);
                }
                ans = max(ans,dp[i]);
            }
            printf("%d
    ",ans);
        }
        return accept;
    }
    

    (2) (O(n^2))
    (d[i] = 长度为i+1)的递增子序列中末尾的最小值(不存在就是INF)
    最开始用INF初始化dp数组的值,然后从前往后考虑数列的元素,对于每个(a_j),如果(i) 处于第一个位置 或者(a[j] >= a[i],)使得(a[j] = a[i])并且(break),最后第一个dp数组中值为INF的下标即为结果
    实际上很类似单调栈,将数组依次后移,如果遇到比前面dp小的就将其放在dp第一个比该值大的前一位(实现单调栈类似的效果),但是长度仍然按照最长计算。
    因为要使得子序列最长,从贪心的角度来想如果该序列足够长,我们尽量使每个递增的差值最小,这样就能排更多的值。

    #include <bits/stdc++.h>
    #define IOS ios::sync_with_stdio(0); cin.tie(0);
    #define accept 0
    #define mp make_pair
    using namespace std;
    typedef long long ll;
    typedef unsigned long long ull;
    typedef pair<int, int> pii;
    const int inf = 0x3f3f3f3f;
    const int maxn = 1e3+7;
    const int maxm = 1e6+7;
    const int mod = 1e9+7;
    
    int n;
    int arr[maxn];
    int dp[maxn];
    int main() {
        int n;
        while(~scanf("%d",&n)){
            for(int i=1;i<=n;i++){
                scanf("%d",&arr[i]);
            }
            for(int i=1;i<=maxn;i++){
            	dp[i] = inf;
    		}
            dp[0] = 0;
            for(int i = 1; i <= n; i++) {
                for(int j = 1; j <= n; j++) {
                    if(i == 1|| dp[j] >= arr[i])  {
                        dp[j] = arr[i]; break;
                    }
                }
            }
            int ans = 0;
            while(dp[ans] != inf) ans++;
            printf("%d
    ", ans-1);
        }
        return 0;
    }
    

    (3)(O(nlogn))
    从第二种方法就能看出来,对于查找部分,我们不必要再遍历比较,可以使用二分进行优化

    #include <bits/stdc++.h>
    #define IOS ios::sync_with_stdio(0); cin.tie(0);
    #define accept 0
    #define mp make_pair
    using namespace std;
    typedef long long ll;
    typedef unsigned long long ull;
    typedef pair<int, int> pii;
    const int inf = 0x3f3f3f3f;
    const int maxn = 1e3+7;
    const int maxm = 1e6+7;
    const int mod = 1e9+7;
    
    int n;
    int arr[maxn];
    int dp[maxn];
    int main() {
        int n;
        while(~scanf("%d",&n)){
            for(int i=1;i<=n;i++){
                scanf("%d",&arr[i]);
                dp[i] = inf; 
            }
            dp[0] = 0;
            for(int i = 1; i <= n; i++) {
                *lower_bound(dp+1,dp+n+1,arr[i]) = arr[i];
            }
            int ans = lower_bound(dp+1,dp+1+n,inf) - dp;
            printf("%d
    ", ans-1);
        }
        return 0;
    }
    
  • 相关阅读:
    [oldboy-django][2深入django]老师管理--查看,添加,编辑
    全虚拟化和半虚拟化的区别 cpu的ring0~ring3又是什么概念?
    Ansible Jinja if 生成不同的MySQL文件
    Linux内核优化(未注释)
    CentOS7入门到精通实战课程课后习题
    基于sersync海量文件实时同步
    CentOS6系统优化
    lnmp架构实现动态php
    云计算与虚拟化KVM深度实践
    Linux6系统安装
  • 原文地址:https://www.cnblogs.com/Tianwell/p/11415894.html
Copyright © 2020-2023  润新知