POJ 1836 Alignment 【最长上升(下降)子序列】
来源:互联网 发布:软件行业会计核算 编辑:程序博客网 时间:2024/04/27 16:09
题目链接:http://poj.org/problem?id=1836
题目大意:对一排士兵重新排序,使新队列每个兵向左或向右都能看到左端或者右端,也就是使新队列的每个士兵的身高呈三角形分布即可。求出需要让最少多少个士兵能完成。
解法:此处借用小优博客的图说明这个问题,对士兵们进行遍历,使每个士兵作为下图的绿色柱子,下一个士兵作为红色柱子,然后每次循环求出绿色士兵之前最长上升子序列,以及红色士兵之后的最长下降子序列,士兵总人数减去这两个数之和,就得到了结果,然后在比较出最小的数就行了。
在这里,求最长上升子序列的方法如果用一般的方法,则复杂度为O(n^2),放在这里总的复杂度就成了O(n^3)对于这题来说一定超时了,所以只能用另一种复杂度为O(n*logn)的求法。关于这种算法的解释,参见:http://www.cnblogs.com/waytofall/archive/2012/09/10/2678576.html
代码:
#include <iostream>#include <cstdio>using namespace std;#define N 1001int n,ans,temp_ans1,temp_ans2;double temp;double h[N];double a[N];int B_Search_1(double a[],int head,int tail,double x){ int low=head,high = tail,mid; while(low<=high) { mid = (low+high)/2; if (a[mid]==x)return mid; else if(a[mid]>x)high = mid-1; //即中间值大于x,在下半段 else low = mid+1; //中间值小于x,在上半段 } return low;}int B_Search_2(double a[],int head,int tail,double x){ int low=head,high = tail,mid; while(low<=high) { mid = (low+high)/2; if (a[mid]==x)return mid; else if(a[mid]<x)high = mid-1; //即中间值大于x,在下半段 else low = mid+1; //中间值小于x,在上半段 } return low;}int main(){ scanf("%d",&n); a[0]=-1; for(int i=1;i<=n;i++) { scanf("%lf",&h[i]); a[i]=3; //设置为无穷大, } for(int i=1;i<=n;i++) { temp_ans1=0; temp_ans2=0; a[0]=-1; for(int m=1;m<=n;m++) a[m]=3; for(int j=1;j<=i;j++) { int t=B_Search_1(a,0,i,h[j]); if(a[t]==3) temp_ans1++; a[t]=h[j]; } a[0]=3; for(int m=1;m<=n;m++) a[m]=-1; for(int j=i+1;j<=n;j++) { int t=B_Search_2(a,i+1,n,h[j]); if(a[t]==-1) temp_ans2++; a[t]=h[j]; //temp_ans2=max(temp_ans2,t)-1; } ans=max(ans,temp_ans1+temp_ans2); } printf("%d\n",n-ans); return 0;}
0 0
- poj 1836 Alignment( 最长上升(下降)子序列 )
- POJ 1836 Alignment 【最长上升(下降)子序列】
- POJ 1836 Alignment(DP max(最长上升子序列 + 最长下降子序列))
- poj 1836 Alignment -dp(合唱队形变式)-最长上升子序列+最长下降子序列
- POJ 1836 Alignment (最长上升 下降子序列)
- POJ 1836 Alignment 最长上升(下降)子序列(dp)
- [poj 1836] Alignment 最长上升子序列
- poj 1836 Alignment(最长上升子序列)
- POJ 1836Alignment(DP最长上升子序列)
- POJ 1836 Alignment LIS变形(最长上升子序列)
- poj-1836 最长上升/下降子序列
- 【最长下降子序列+有难度】北大 poj 1836 Alignment
- POJ1836-Alignment(最长上升子序列)
- poj 1836 Alignment (最长上升子序列 N*log(n))@
- 最长上升下降子序列
- POJ-1836 Alignment (Romania OI 2002 线性dp 最长上升子序列)
- poj 1836 Alignment 最长递增子序列
- (POJ1836)Alignment <DP,最长上升子序列变形>
- Comparable与Comparator的使用
- 凸包代码,摘自入门经典训练指南
- 小白如何才能拿到知名IT企业的offer
- 如何把SEH类型的系统异常转化为C++类型的异常
- 快排
- POJ 1836 Alignment 【最长上升(下降)子序列】
- C++课程设计
- 异常处理与MiniDump详解(1) C++异常
- 利用idapro6.5
- 【LeetCode】Edit Distance
- HTTP深入浅出 http请求
- H263、H264和3GPP、MPEG4是什么关系
- 异常处理与MiniDump详解(2) 智能指针与C++异常
- 如何写build.xml