zoukankan      html  css  js  c++  java
  • BZOJ 1609 [Usaco2008 Feb]Eating Together麻烦的聚餐:LIS & LDS (nlogn)

    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1609

    题意:

      给你一个只由数字"1,2,3"组成的序列a[i],共n个数。

      你可以任意更改这些数字,使得序列中每一种数字都“站在一起”,并且单调不减或不增。

      例如:"1111222", "332211"...

      问你至少更改多少个数字。

    题解:

      单调不减:求原序列LIS(最长非降子序列),当前答案t1 = n - LIS.

      单调不增:求原序列LDS(最长非升子序列),当前答案t2 = n - LDS.

      最终答案ans = min(t1,t2).

      注:n为30000,求LIS & LDS用nlogn方法。

    AC Code:

     1 #include <iostream>
     2 #include <stdio.h>
     3 #include <string.h>
     4 #define MAX_N 30005
     5 
     6 using namespace std;
     7 
     8 int n;
     9 int a[MAX_N];
    10 int d[MAX_N];
    11 
    12 int cal_lis()
    13 {
    14     int len=1;
    15     d[1]=a[0];
    16     for(int i=1;i<n;i++)
    17     {
    18         if(a[i]>=d[len])
    19         {
    20             d[++len]=a[i];
    21             continue;
    22         }
    23         int lef=1;
    24         int rig=len;
    25         while(rig-lef>1)
    26         {
    27             int mid=(lef+rig)/2;
    28             if(a[i]>=d[mid]) lef=mid;
    29             else rig=mid;
    30         }
    31         int ans;
    32         if(a[i]<d[lef]) ans=0;
    33         else ans=lef;
    34         d[ans+1]=min(d[ans+1],a[i]);
    35     }
    36     return len;
    37 }
    38 
    39 int cal_lds()
    40 {
    41     int len=1;
    42     d[1]=a[0];
    43     for(int i=1;i<n;i++)
    44     {
    45         if(a[i]<=d[len])
    46         {
    47             d[++len]=a[i];
    48             continue;
    49         }
    50         int lef=1;
    51         int rig=len;
    52         while(rig-lef>1)
    53         {
    54             int mid=(lef+rig)/2;
    55             if(a[i]<=d[mid]) lef=mid;
    56             else rig=mid;
    57         }
    58         int ans;
    59         if(a[i]>d[lef]) ans=0;
    60         else ans=lef;
    61         d[ans+1]=max(d[ans+1],a[i]);
    62     }
    63     return len;
    64 }
    65 
    66 int main()
    67 {
    68     cin>>n;
    69     for(int i=0;i<n;i++)
    70     {
    71         cin>>a[i];
    72     }
    73     int v1=cal_lis();
    74     int v2=cal_lds();
    75     cout<<n-max(v1,v2)<<endl;
    76 }
  • 相关阅读:
    Ubuntu18.04 一些好用的扩展
    Java并发编程:volatile关键字解析
    SpringCloud(0) 外行人都能看懂的SpringCloud,错过了血亏!
    Java8中的流操作-基本使用&性能测试
    JDBC基本操作
    单例模式(二)
    单例模式(一)static、final和单例模式
    Lombok的使用与原理
    Linux下出现permission denied的解决办法
    虚拟机安装
  • 原文地址:https://www.cnblogs.com/Leohh/p/7604687.html
Copyright © 2011-2022 走看看