POJ 1836 Alignment
有一排人,身高可能不同,现在有一个理想状态是这排的每个人向左或向右看没有被挡住视野(当遇到等高或更高的人时会被挡住),现在问最少让几人出列可以达到这个理想状态。
最少人出列,其实就是一个人数最多的理想状态。求一个人数最多的类似"山峰"的高度排列。那就可以从左到右、从右到左各求一遍LIS
开始用 O(n2)的写法WA了,错在搞错dp[i] 的含义,dp[i]代表以i为尾的LIS,最后输出答案时应该枚举 dp[i]+dp[j]
1 #include <cstdio> 2 #include <algorithm> 3 using namespace std; 4 5 int height[1024]; 6 int dp1[1024];//up 7 int dp2[1024];//down 8 9 int main(){ 10 int N; 11 scanf("%d",&N); 12 for(int i=0;i<N;++i){ 13 double tmp; 14 scanf("%lf",&tmp); 15 height[i]=tmp*100000+0.1; 16 } 17 for(int i=0;i<N;++i){ 18 dp1[i]=1; 19 for(int j=0;j<i;++j){ 20 if(height[j]<height[i]) dp1[i]=max(dp1[i],dp1[j]+1); 21 } 22 } 23 for(int i=N-1;i>=0;i--){ 24 dp2[i]=1; 25 for(int j=N-1;j>i;--j){ 26 if(height[j]<height[i]) dp2[i]=max(dp2[i],dp2[j]+1); 27 } 28 } 29 //for(int i=0;i<N;++i) printf("i : %d\tup: %d , down: %d\n",i,dp1[i],dp2[i]); 30 int ans=-1; 31 //ans=max(ans,dp2[0]); 32 //for(int i=0;i<N-1;++i)ans=max(ans,dp1[i]+dp2[i+1]); 33 //ans=max(ans,dp1[N-1]); 34 for(int i=0;i<N;++i) 35 for(int j=i+1;j<N;++j) 36 ans=max(ans,dp1[i]+dp2[j]); 37 printf("%d\n",N-ans); 38 }
View Code
用O(nlogn)的写法
1 #include <cstdio> 2 #include <algorithm> 3 using namespace std; 4 5 const int INF=0x3f3f3f3f; 6 int height[1024]; 7 int dp1[1024];//up 8 int dp2[1024];//down 9 int S[1024]; 10 int tot; 11 12 int B_S(int l,int r,int ob){ 13 int mid; 14 r--; 15 while(l<=r){ 16 mid=(l+r)>>1; 17 if(S[mid]>ob) r=mid-1; 18 else l=mid+1; 19 } 20 return l; 21 } 22 23 int main(){ 24 int N; 25 scanf("%d",&N); 26 for(int i=0;i<N;++i){ 27 double tmp; 28 scanf("%lf",&tmp); 29 height[i]=tmp*100000+0.1; 30 } 31 32 fill(S,S+N,INF); 33 for(int i=0;i<N;++i){ 34 int pos=lower_bound(S,S+N,height[i])-S; 35 dp1[i]=pos+1; 36 S[pos]=height[i]; 37 } 38 fill(S,S+N,INF); 39 for(int i=N-1;i>=0;i--){ 40 int pos=lower_bound(S,S+N,height[i])-S; 41 dp2[i]=pos+1; 42 S[pos]=height[i]; 43 } 44 //for(int i=0;i<N;++i) printf("i : %d\tup: %d , down: %d\n",i,dp1[i],dp2[i]); 45 int ans=-1; 46 //ans=max(ans,dp2[0]); 47 //for(int i=0;i<N-1;++i)ans=max(ans,dp1[i]+dp2[i+1]); 48 //ans=max(ans,dp1[N-1]); 49 for(int i=0;i<N;++i) 50 for(int j=i+1;j<N;++j) 51 ans=max(ans,dp1[i]+dp2[j]); 52 printf("%d\n",N-ans); 53 }
View Code
1 #include <cstdio> 2 #include <algorithm> 3 using namespace std; 4 5 int height[1024]; 6 int dp1[1024];//up 7 int dp2[1024];//down 8 int S[1024]; 9 int tot; 10 11 int B_S(int l,int r,int ob){ 12 int mid; 13 r--; 14 while(l<=r){ 15 mid=(l+r)>>1; 16 if(S[mid]>ob) r=mid-1; 17 else l=mid+1; 18 } 19 return l; 20 } 21 22 int main(){ 23 int N; 24 scanf("%d",&N); 25 for(int i=0;i<N;++i){ 26 double tmp; 27 scanf("%lf",&tmp); 28 height[i]=tmp*100000+0.1; 29 } 30 tot=0; 31 for(int i=0;i<N;++i){ 32 if(tot==0||S[tot-1]<height[i]) S[tot++]=height[i]; 33 else{ 34 //int pos=B_S(0,tot,height[i]); 35 int pos=lower_bound(S,S+tot,height[i])-S; 36 S[pos]=height[i]; 37 } 38 dp1[i]=tot; 39 } 40 tot=0; 41 for(int i=N-1;i>=0;i--){ 42 if(tot==0||S[tot-1]<height[i]) S[tot++]=height[i]; 43 else{ 44 //int pos=B_S(0,tot,height[i]); 45 int pos=lower_bound(S,S+tot,height[i])-S; 46 S[pos]=height[i]; 47 } 48 dp2[i]=tot; 49 } 50 //for(int i=0;i<N;++i) printf("i : %d\tup: %d , down: %d\n",i,dp1[i],dp2[i]); 51 int ans=-1; 52 //ans=max(ans,dp2[0]); 53 //for(int i=0;i<N-1;++i)ans=max(ans,dp1[i]+dp2[i+1]); 54 //ans=max(ans,dp1[N-1]); 55 for(int i=0;i<N;++i) 56 for(int j=i+1;j<N;++j) 57 ans=max(ans,dp1[i]+dp2[j]); 58 printf("%d\n",N-ans); 59 }
View Code
一种单调栈,一种从修改预设数组,都是二分
开始一直在用upper_bound,后来脑补跑数据才发现,upper_bound只能用来找不下降子序列,lower_bound是用来找严格上升子序列。
转载于:https://www.cnblogs.com/Kiritsugu/p/9581702.html
POJ 1836 Alignment相关推荐
- poj 1836 Alignment
题目大意: 给定一排人的身高,求踢出最少的人可以使队列身高如下形状: Description In the army, a platoon is composed by n soldiers. Dur ...
- 【POJ - 1836】Alignment(dp,LIS,最长上升子序列类问题)
题干: In the army, a platoon is composed by n soldiers. During the morning inspection, the soldiers ar ...
- POJ前面的题目算法思路【转】
1000 A+B Problem 送分题 49% 2005-5-7 1001 Exponentiation 高精度 85% 2005-5-7 1002 487-3279 n/a 90% 2005-5- ...
- POJ 超详细分类
POJ 各题算法 1000 A+B Problem 送分题 49% 2005-5-7 1001 Exponentiation 高精度 ...
- POJ的题目分类(两个版本)
版本一: 简单题 1000A+B Problem 1001Exponentiation 1003 Hangover 1004 Financial Management 1005 I Think I N ...
- 南京大学计算机系本科生开放日,2018/7
2018/7/26 环境 计算机系位于南大仙林校区,树很多,绿化不错. 开放日全程包食宿,食堂很好吃,南大国际会议中心的早餐更厉害. 外地学生住南大国际会议中心或中公汇悦酒店.南大国际会议中心标准双人 ...
- 1836:Alignment
题目Alignment 大意: n个军人按他们的序号排成一列 现在挑出一些人,剩下的军人相对位置不变. 则剩下队列中的军人至少可以看到这个队的某一端(当从军人的位置到端点的位置,不存在比他高或者与其身 ...
- hdu与poj题目分类
POJ 初期: 一.基本算法: (1)枚举. (poj1753,poj2965) (2)贪心(poj1328,poj2109,poj2586) (3)递归和分治法. (4)递推. (5)构造法.(po ...
- (精)【ACM刷题之路】POJ题目详细多角度分类及推荐题目
POJ上的一些水题(可用来练手和增加自信) (poj3299,poj2159,poj2739,poj1083,poj2262,poj1503,poj3006,poj2255,poj3094) 初期: ...
最新文章
- OpenCV(基础补充)颜色空间HSV *args与**args(滑动条传参问题)
- ConcurrentHashMap总结
- 发展之道:简单与专注 王泽宾
- java 反射深度克隆_C#使用反射(Reflection)实现深复制与浅复制
- mysql 高效备份_Mysql高性能备份方案解决数据不间断访问(LVM快照方式备份)
- axis2 jar包冲突_一个jar包冲突引起的StackOverflowError
- 九、给小白看的第二篇Python基础教程
- 科罗拉多大学 C#游戏编程课程总结
- SpringBoot - 资源国际化
- Divergent series
- 2017级计科新生游戏大作业制作讲解
- 电类专业(自动化、电气、电子、电力、通信等)的大学四年应该怎么过呢_史蒂文森sun_新浪博客
- 人工智能研究中心快递柜——代码分析七
- 华硕主板M2N-电源跳线怎么接
- 迷宫问题----经典回溯法解决
- Java后端技术框架
- WGS84坐标系转为西安80坐标系的解决方式
- vue技术分享ppt_胡中南:Web端GIS技术新进展 | GTC专题论坛报告(视频+PPT+速记)
- Meteor 初级入门 三
- 嵌入式–滑动平均滤波算法