POJ1836 Alignment DP最长队列问题

来源:互联网 发布:甜品软件 编辑:程序博客网 时间:2024/05/29 09:43

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

93 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;}