SCAU周训8-A:POJ - 1836

1.题目描述:

2.题意:
让你从原序列中抽出几个人,使得每个人都可以看不到左边或者右边的人。最少抽出多少个人?!

3.思路:
DP[LIS]。 如果要看不到人,那么必定这个队列是一个单调的序列,但是它可以选择方向,那么就是一个类似于三角形一样的序列,从中间往两边递减。要求最少的人,我们就要求一个最长的递增序列的长度,典型LIS。这题两边的思路可以直接变成从头一次,然后反过来再一次。那么组合的时候就选左边一个,右边一个,选最大的就OK了。

4.代码:

//A
#include
#define rep(i,a,b) for(int i=(a);i<(b);++i)
#define per(i,b,a) for(int i=(b)-1;i>=(a);--i)
using namespace std;

const int maxn=1e5+5;

int n;
double a[maxn];
int dp1[maxn],dp2[maxn];
inline void solve()
{
	cin>>n;
	rep(i,1,n+1)
	{
		cin>>a[i];
		dp1[i]=dp2[i]=1;
	}
	rep(i,1,n+1)
		rep(j,1,i)
			if(a[j]<a[i])
				dp1[i]=max(dp1[i],dp1[j]+1);
	per(i,n+1,1)
		per(j,n+1,i+1)
			if(a[j]<a[i])
				dp2[i]=max(dp2[i],dp2[j]+1);
	int res=0;
	rep(i,1,n+1)
		rep(j,i+1,n+1)
			res=max(res,dp1[i]+dp2[j]);
	cout<<n-res<<endl;
}

int main()
{
	solve();
	return 0;
}

你可能感兴趣的:(SCAU周训)