zoukankan      html  css  js  c++  java
  • 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;
    }
    
  • 相关阅读:
    vs2010 + .net3.5 MSCharts使用介绍与例子
    TFS服务连接TF31002 出错
    SharePoint CAML 通过时间查询
    SharePoint2010项目总结汇总
    jquery 获取和设置 select下拉框的值
    How to Create Multilingual Webpart in SharePoint 2010 (C# 方式)
    sharepoint母版页固定宽度与纵向滚动条靠右边(修改版)
    JavaScript进行GET和POST请求
    端口简介大全
    程序员学习能力提升三要素
  • 原文地址:https://www.cnblogs.com/Tianwell/p/11415894.html
Copyright © 2011-2022 走看看