poj1836 Alignment (DP,线性LIS)
题目链接:https://vjudge.net/problem/POJ-1836
题意:令到原队列的最少士兵出列后,使得新队列任意一个士兵都能看到左边或者右边的无穷远处。就是使新队列呈三角形分布就对了。即左边的递增序列人数和右边的递减序列人数之和最大因而可转化为求“最长不降子序列”和“最长不升子序列”问题。进一步转化为从头部求出最长不下降子序列与从尾部求出最长不下降子序列即可,分别求出二者的大小,最后用队列长度减去二者之和就是我们所求的出列的士兵个数。
最长上升子序列:https://www.cnblogs.com/frankchenfu/p/7107019.html
#include <iostream> #include <cstring> using namespace std; const int maxn=1000+10; int n; double l[maxn]; int f1[maxn],f2[maxn]; int main() { ios::sync_with_stdio(false); cin>>n; for(int i=1;i<=n;i++) cin>>l[i]; for(int i=1;i<=n;i++){ f1[i]=1; f2[i]=1; } for(int i=1;i<=n;i++) { for(int j=1;j<i;j++) { if(l[j]<l[i]) f1[i]=max(f1[i],f1[j]+1); } } for(int i=n;i>=1;i--) { for(int j=n;j>i;j--) { if(l[j]<l[i]) f2[i]=max(f2[i],f2[j]+1); } } int ans=0; for(int i=1;i<n;i++) { for(int j=i+1;j<=n;j++) { ans=max(ans,f1[i]+f2[j]); } } cout<<(n-ans)<<endl; return 0; }