zoukankan      html  css  js  c++  java
  • 各种子序列问题

    最长严格上升子序列

    LIS问题,动归时间复杂度o(n2),可以用单调队列优化到o(nlogn)

    http://blog.csdn.net/dangwenliang/article/details/5728363

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    using namespace std;
    int n,dp[5005],orz[5005],ans = 0;
    int main(){
        cin>>n;
        for(int i = 1;i <= n;i++) scanf("%d",&orz[i]);
        for(int i = 1;i <= n;i++){
            dp[i] = 1;
            for(int j = 1;j < i;j++){
                if(orz[i] > orz[j])dp[i] = max(dp[i],dp[j]+1);
                ans = max(ans,dp[i]);
            }
        }
        cout<<ans;
        return 0;
    }
    #include <iostream>
    using namespace std;
    int find(int *a,int len,int n)//修改后的二分查找,若返回值为x,则a[x]>=n
    {
        int left=0,right=len,mid=(left+right)/2;
        while(left<=right)
        {
           if(n>a[mid]) left=mid+1;
           else if(n<a[mid]) right=mid-1;
           else return mid;
           mid=(left+right)/2;
        }
        return left;
    }
         
    int main(void)
    {
        int n,a[100],c[100],i,j,len;//新开一变量len,用来储存每次循环结束后c中已经求出值的元素的最大下标
        while(cin>>n)
        {
            for(i=0;i<n;i++)
                cin>>a[i];
            b[0]=1;
            c[0]=-1;
            c[1]=a[0];
            len=1;//此时只有c[1]求出来,最长递增子序列的长度为1.
            for(i=1;i<n;i++)
            {
                j=find(c,len,a[i]);
                c[j]=a[i];
                if(j>len)//要更新len,另外补充一点:由二分查找可知j只可能比len大1
                    len=j;//更新len
            }
            cout<<len<<endl;
        }
        return 0;
    }

    合唱队形

    #include<iostream>
    #include<cstdio>
    #include<string>
    #include<cstring>
    #include<algorithm>
    
    using namespace std;
    const int maxn = 200;
    int dp[maxn],dps[maxn],value[maxn],n;
    
    int main(){
        cin>>n;
        for(int i =1;i <= n;i++) cin>>value[i];
        dp[1] = dps[n] = 1;
        for(int i = 2;i <= n;i++){
            for(int j = 1;j < i;j++){
                if(dp[j] > dp[i] && value[i] > value[j]) dp[i] = dp[j];
            }
            dp[i]++;
            
        }
        for(int i = n-1;i >= 1;i--){
            for(int j = n;j > i;j--){
                if(dps[j] > dps[i] && value[i] > value[j]) dps[i] = dps[j];
            }
            dps[i]++;
            
        }
        int ans = 0;
        for(int i = 1;i <= n;i++) ans = max(ans,dp[i] + dps[i] - 1);
        cout<<n - ans;
        return 0;
    }
  • 相关阅读:
    uva 10881
    uva 1388
    【USACO 3.2.5】魔板
    【USACO 3.2.4】饲料调配
    【USACO 3.2.3】纺车的轮子
    【USACO 3.2.2】二进制数01串
    【USACO 3.2.1】阶乘
    【USACO 3.1.6】邮票
    【USACO 3.1.5】联系
    【USACO 3.1.4】形成的区域
  • 原文地址:https://www.cnblogs.com/hyfer/p/5811926.html
Copyright © 2011-2022 走看看