洛谷 P1091 合唱队形

题目链接:https://www.luogu.org/problemnew/solution/P1091

思路:先求一遍最长递增子序列(dp1[i]表示以i位置结尾的LIS),再求一遍最长递减子序列(dp2[i]表示以i位置开始的LDS(最长递减子序列),PS:相当于从后往前的最长递增子序列。答案是就是len1+len2-1。

先是我自己的超笨代码(复杂度o(n^2logn))
写出下面这个代码是我对LIS的理解不够,我这个是对每个位置i,求一遍[0,i]的LIS,再求一遍[i,n-1]的LDS,然后再求len1+len2-1

#include 
#include 

using namespace std;

const int maxn=200;

int a[maxn],dp1[maxn],dp2[maxn],b[maxn];

int mfind(int left,int right,int x,int ta) {
    int mid;
    if((ta&&b[right]x))
       return right+1;
    if(ta)
    {
       while(left=x)right=mid;
       }	
    }
    else  {
       while(leftx)left=mid+1;
       	 else if(b[mid]<=x)right=mid;
       	 //cout <> n;
    for(int i=0;i> a[i];
    memset(dp1,0,sizeof(dp1));
    memset(dp2,0,sizeof(dp2));
    int ans=0;
    for(int i=1;i

改正以后的n^2复杂度代码:(因为上面已经写了nlogn的LIS(虽然并没有正确使用)了,所以就不再写了)

#include 
#include 

using namespace std;

const int maxn=200;

int a[maxn],dp1[maxn],dp2[maxn],b[maxn];



int main() {
	int n;
	cin >> n;
	for(int i=0;i> a[i];
    for(int i=0;ia[i])dp1[j]=max(dp1[j],dp1[i]+1);
    for(int i=n-1;i>0;i--)
      for(int j=i-1;j>=0;j--)
      	  if(a[j]>a[i])dp2[j]=max(dp2[j],dp2[i]+1);
    int ans=0;
    for(int i=0;i

你可能感兴趣的:(线性dp)