• 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	up: %d , down: %d
    ",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-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	up: %d , down: %d
    ",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-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	up: %d , down: %d
    ",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-ans);
    59 }
    View Code

    一种单调栈,一种从修改预设数组,都是二分

    开始一直在用upper_bound,后来脑补跑数据才发现,upper_bound只能用来找不下降子序列,lower_bound是用来找严格上升子序列。

  • 相关阅读:
    【APP问题定位(三)】adb安装
    【APP问题定位(一)】夜神模拟器安装及问题
    selenium_Alert
    selenium-iframe操作
    Python+selenium打开网页
    selenium 之 ActionChains (二)
    PyCharm汉化、破解教程
    selenim之ActionChains(一)
    C#连接数据库以及增、删、改、查操作
    C#飞行棋游戏
  • 原文地址:https://www.cnblogs.com/Kiritsugu/p/9581702.html
Copyright © 2020-2023  润新知