关于这题一眼看上去貌似是最长队列问题。题目本意是指,给出一个有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;
}