POJ-1836-Alignment-双向LIS-注意double精度

。。。本题找 一个双向的list。。。


满足  1 2 3 4 4 3 2 1 这样的一个 两端小 中间高的数列,最中间可以等高。其余部分必须严格递减


直接暴力枚举终点,nlog的list

总复杂度 n*n*logn。。。


注意的坑是   double比较要 减去eps。。。不然一直wa


即是此处: int it=upper_bound(dp+1,dp+1+len,tmm[i]-eps)-dp;  


-----------------------------------------

发现并不用枚举中点了。。。两遍lis即可..... 16MS  nlogn


 

#include <cstdio>
#include <cmath>
#include <cstring>
#include <string>
#include <algorithm>
#include <queue>
#include <map>
#include <set>
#include <vector>
#include <iostream>
using namespace std;
 int max(int a,int b)
 {
	 return a<b?b:a;
 }
double eps=0.000001;
double tm[1005],tm2[1005]; 
double dp[1005];
int len1[1005],len2[1005];
int getlis(int l,int r,double tmm[],int lenlen[])
{	
	int len=1,i;
	dp[len]=tmm[l];
	for (i=2;i<=r;i++)
	{
		if (tmm[i]>dp[len])
			dp[++len]=tmm[i];
		else
		{
			int it=upper_bound(dp+1,dp+1+len,tmm[i]-eps)-dp;  
			dp[it]=tmm[i];
		}
		lenlen[i]=len;
	}	
	return len;
}
int main()
{
	int n,i;
	cin>>n;
	for (i=1;i<=n;i++)
	{
		scanf("%lf",&tm[i]);
		tm2[n-i+1]=tm[i];
	}
   getlis(1,n,tm,len1);
	getlis(1,n,tm2,len2);
	int maxx=0; 
		for (i=1;i<=n;i++)
		{ 
			maxx=max(maxx,len1[i]+len2[n-i]);
		} 
	printf("%d\n",n-maxx); 
	return 0;
}

你可能感兴趣的:(POJ-1836-Alignment-双向LIS-注意double精度)