POJ1836 Alignment DP最长队列问题

关于这题一眼看上去貌似是最长队列问题。题目本意是指,给出一个有n个元素的队列,从里面踢掉最少的元素,使得队伍中的元素往左看或者往右看,都可以看到队列的端点。对于WA,我给一个下面的数据,看看你们结果是怎样

9
3 4 5 1 2 5 4 3 3

正确答案应该是3。因为两个5都可以留下来,只需要踢掉1,2,3就可以了。

这题先从0..n-1求最长队列DP1,再从n-1..0求最长队列DP2,这样必有双向队列的最长队列为n-max(DP1[i]+DP2[i]-1)。由于要考虑到存在两个并列的最大值,故同时记录下此时达到最大值的i为maxindex,再往左搜索看看有没有存在并列最大值且DP1也相同,如果相同队列还需要加1.

以下为代码

/*******************************************************************************
 * Author : Neo Fung
 * Email : neosfung@gmail.com
 * Last modified : 2011-07-20 17:07
 * Filename : POJ1836 Alignment.cpp
 * Description : http://poj.org/problem?id=1836
 * *****************************************************************************/
// POJ1836 Alignment.cpp : Defines the entry point for the console application.
//

// #include "stdafx.h"



#include <fstream>
#include <stdio.h>
#include <iostream>
#include <string.h>
#include <string>
#include <vector>
#include <stack>
#include <deque>
#include <map>
#include <math.h>
#include <algorithm>
#include <numeric>
#include <functional>
#include <memory.h>

using namespace std;

int main(void)
{
// 	ifstream cin("data.txt");
	int DP[1001];
	int DP2[1001];
	double height[1001];
	int n;
	int maxdp,maxdp2;

	cin>>n;
	for(int i=0;i<n;++i)
	{
		cin>>height[i];
	}
	DP[0]=1;
	DP2[n-1]=1;

	for(int i=1;i<n;++i)
	{
		maxdp=1;
		for(int j=i-1;j>=0;--j)
		{
			if(height[i]>height[j] && DP[j]>=maxdp) maxdp=DP[j]+1;
		}
		DP[i]=maxdp;
	}

	for(int i=n-2;i>=0;--i)
	{
		maxdp2=1;
		for (int j=i+1;j<n;++j)
		{
			if(height[i]>height[j] && DP2[j]>=maxdp2) maxdp2=DP2[j]+1;
		}
		DP2[i]=maxdp2;
	}

	maxdp=0;
	int maxindex;

	for (int i=0;i<n;++i)
	{
		if (maxdp<=DP[i]+DP2[i])
		{
			maxdp=DP[i]+DP2[i];
			maxindex = i;
		}
	}

	for (int i=0;i<maxindex;++i)
	{
		if (height[i]==height[maxindex])
		{
			++maxdp;
		}
	}

	cout<<n-maxdp+1<<endl;


	return 0;
}




你可能感兴趣的:(POJ1836 Alignment DP最长队列问题)