动态规划-最长不下降子序列

代码:

#include <stdio.h>
#include <memory.h>
#include <math.h>
#include <string>
#include <vector>
#include <set>
#include <stack>
#include <queue>
#include <algorithm>
#include <map>


#define I scanf
#define OL puts
#define O printf
#define F(a,b,c) for(a=b;a<c;a++)
#define FF(a,b) for(a=0;a<b;a++)
#define FG(a,b) for(a=b-1;a>=0;a--)
#define LEN 101
#define MAX 1<<30
#define V vector<int>

using namespace std;

int a[LEN];
int dp[LEN];
int n;

void printAns(int cnt,int pos,V vec){
    vec.insert(vec.begin(),a[pos]);
    int obj=dp[pos--]-1;
    while(pos>0){
        if(dp[pos]==obj)
            printAns(cnt-1,pos,vec);
        pos--;
    }
    if(cnt==1){
        int i;
        FF(i,vec.size())
            O("%d ",vec[i]);
        OL("");
    }
}

void DP_n2(){
    int i,j,p;
    int ans=0;
    F(i,1,n+1){
        dp[i]=1;
        F(j,1,i){
            if(a[j]<a[i])
                dp[i]=max(dp[i],dp[j]+1);
        } 
        if(dp[i]>ans){
            ans=dp[i];
            p=i;
        }
    }
    O("ans=%d p=%d
序列 :
",ans,p);
    F(i,1,n+1)O("%d ",a[i]) ;
    OL("
DP数组 :");
    F(i,1,n+1)O("%d ",dp[i]) ;
    OL("");
    V vec;
    OL("所有LIS :");
    printAns(ans,p,vec);
} 

void DP_nLogn(){
    int i,j,top=0;
    F(i,1,n+1){
        if(top==0 || dp[top-1]<a[i]) 
            dp[top++]=a[i];
        else{
            int pos=lower_bound(dp,dp+top,a[i])-dp;
            dp[pos]=a[i];
        }
    }
    printf("%d
",top);
    OL("DP数组: ");
    F(i,0,top)O("%d ",dp[i]);
    OL("
") ;
}
int main()
{   
//dilworth定理:LIS 长度   等于  LIS 子序列 个数
    freopen("LIS.txt","r",stdin);
    int i,j;
    I("%d",&n);
    F(i,1,n+1){
        I("%d",&a[i]);
    }
    
    DP_nLogn();
    DP_n2();
    return 0;
}
View Code

测试数据:

11
1 3 7 6 8 5 3 2 7 2 9

OJ:导弹拦截

#include <stdio.h>
#include <memory.h>
#include <math.h>
#include <string>
#include <vector>
#include <set>
#include <stack>
#include <queue>
#include <algorithm>
#include <map>


#define I scanf
#define OL puts
#define O printf
#define F(a,b,c) for(a=b;a<c;a++)
#define FF(a,b) for(a=0;a<b;a++)
#define FG(a,b) for(a=b-1;a>=0;a--)
#define LEN 100001
#define MAX 1<<30
#define V vector<int>

using namespace std;

int a[LEN];
int dp1[LEN];//increase
int dp2[LEN];//decrease

bool cmp(int x,int y){
    return x>y;
}

int main(){
    freopen("D:/CbWorkspace/动态规划/导弹拦截.txt","r",stdin);
    int i,n=0; 
    while(I("%d",&a[++n])>0);
    n--;
    fill(dp2,dp2+n+1,MAX);
    int len1=0,len2=0;
    F(i,1,n+1){
        //记录递增dp
        int p1=upper_bound(dp1+1,dp1+1+n,a[i],cmp)-dp1;    //在递减序列中进行操作 
        //记录递减dp(初始化Inf)
        int p2=lower_bound(dp2+1,dp2+1+n,a[i])-dp2;        //在递增序列中进行操作 
        dp1[p1]=a[i] ;
        dp2[p2]=a[i] ;
        len1=max(len1,p1);
        len2=max(len2,p2);
        int s=0;
    }
    O("%d
%d",len1,len2);
    return 0;
}
View Code

OJ : 合唱队形

#include <stdio.h>
#include <memory.h>
#include <math.h>
#include <string>
#include <vector>
#include <set>
#include <stack>
#include <queue>
#include <algorithm>
#include <map>


#define I scanf
#define OL puts
#define O printf
#define F(a,b,c) for(a=b;a<c;a++)
#define FF(a,b) for(a=0;a<b;a++)
#define FG(a,b) for(a=b-1;a>=0;a--)
#define LEN 100001
#define MAX 1<<30
#define V vector<int>

using namespace std;

int dp1[LEN] ;
int dp2[LEN] ;
int a[LEN] ;
int max1[LEN] ;
int max2[LEN] ;

bool cmp(int x,int y){
    return x>y;
}

int main(){
//    freopen("D:/CbWorkspace/动态规划/合唱队形.txt","r",stdin);
    int n,i,j;
    I("%d",&n);
    FF(i,n)
        I("%d",&a[i]);
    int max_ans=0;
    FF(i,n){
        dp1[i]=1;
        FF(j,n){
            if(a[j]<a[i]){
                dp1[i]=max(dp1[i],dp1[j]+1);
            }
        }
        max_ans=max(max_ans,dp1[i]);
        max1[i]=max_ans;
    }
    max_ans=0;
    for(i=n-1;i>=0;i--){
        dp2[i]=1;
        for(j=n-1;j>i;j--){
            if(a[i]>a[j]){
                dp2[i]=max(dp2[i],dp2[j]+1);
            }
        }
        max_ans=max(max_ans,dp2[i]);
        max2[i]=max_ans;
    }
    int ans=0;
    FF(i,n-1){
        int t=max1[i]+max2[i+1];
        ans=max(ans,t);
    }
    O("%d",n-ans);
    return 0;
}
View Code
原文地址:https://www.cnblogs.com/TQCAI/p/8428598.html