zoukankan      html  css  js  c++  java
  • hdu3525 Orienteering

    最长公共子序列nlogn神算法,线段树换了几种姿势,怎么搞都超时,把他转换成LIS就AC了

    A :  3 3 1 1 2 2

    B :  3 2 3 1 2 1

    B中的每个元素在A中的位置倒序再放入B中可得 {2,1}{6,5}{2,1}{4,3}{6,5}{4,3}

    我们发现,B中的每一个大括号取一个数,对应A中的匹配加1,而要使A的标号递增,就把每个括号按递减顺序排列,然后对这个序列求LIS就是答案。

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <map>
     4 #include <vector>
     5 #include <cstring>
     6 #include <set>
     7 #include <algorithm>
     8 #define maxn 200010
     9 using namespace std;
    10 int t,n,m;
    11 int fa[maxn],fb[maxn];
    12 vector<int> za,zb;
    13 vector<int> w[10010];
    14 set<int> qa,qb;
    15 int v[maxn*5],ct;
    16 void init(){
    17     za.clear(),zb.clear();
    18     memset(fa,0,sizeof fa);
    19     memset(fb,0,sizeof fb);
    20     qa.clear(),qb.clear();
    21     for(int i=0;i<10010;i++) w[i].clear();
    22 }
    23 void read(){
    24     scanf("%d%d",&n,&m);
    25     int c,x;
    26     for(int i=1;i<=2*n*m;i++) qa.insert(i);
    27     for(int i=1;i<=2*n*m;i++) qb.insert(i);
    28     for(int i=0;i<n*m;i++){
    29        scanf("%d%d",&c,&x);
    30        set<int>::iterator at=qa.lower_bound(x);
    31        if(at!=qa.end()){
    32           fa[*at]=c;
    33           qa.erase(at);
    34        }
    35     }
    36     for(int i=0;i<n*m;i++){
    37        scanf("%d%d",&c,&x);
    38        set<int>::iterator at=qb.lower_bound(x);
    39        if(at!=qb.end()){
    40           fb[*at]=c;
    41           qb.erase(at);
    42        }
    43     }
    44     for(int i=1;i<=2*m*n;i++){
    45        if(fa[i]) za.push_back(fa[i]);
    46     }
    47     for(int i=0;i<n*m;i++){
    48        w[za[i]].push_back(i+1);
    49     }
    50     for(int i=1;i<=2*m*n;i++){
    51        if(fb[i]) zb.push_back(fb[i]);
    52     }
    53 }
    54 int gao_LIS(int a[],int len){
    55     int ret=0;
    56     int b[maxn];
    57     b[ret++]=a[0];
    58     for(int i=1;i<len;i++){
    59         int x=lower_bound(b,b+ret,a[i])-b;
    60         if(x==ret){
    61            b[ret++]=a[i];
    62         }else{
    63            b[x]=a[i];
    64         }
    65     }
    66     return ret;
    67 }
    68 void solve(int ca){
    69     ct=0;
    70     for(int i=0;i<n*m;i++){
    71        int nn=w[zb[i]].size();
    72        for(int j=nn-1;j>=0;j--){
    73           v[ct++]=w[zb[i]][j];
    74        }
    75     }
    76     printf("Case #%d: %d
    ",ca,gao_LIS(v,ct));
    77 }
    78 int main(){
    79     scanf("%d",&t);
    80     for(int ca=1;ca<=t;ca++){
    81        init();
    82        read();
    83        solve(ca);
    84     }
    85     return 0;
    86 }
    hdu3525

     还有一种线段树做法,

    http://wenku.baidu.com/link?url=cZXjwqZqwjIUPS7-pUU4jr7zZD1T7N6Ue635ka2dYm4dZ2d0zVw_0vSJ28rqI57L1KnbVjHp6fh_0-qkkAHIg4QEsvifI5FeuX68C7Ls0sG

  • 相关阅读:
    diary and html 文本颜色编辑,行距和其它编辑总汇
    bash coding to changeNames
    virtualbox ubuntu 网络连接 以及 连接 secureCRT
    linux 学习6 软件包安装
    linux 学习8 权限管理
    vim 使用2 转载 为了打开方便
    ubuntu
    linux 学习15 16 启动管理,备份和恢复
    linux 学习 14 日志管理
    linux 学习 13 系统管理
  • 原文地址:https://www.cnblogs.com/wonderzy/p/3434269.html
Copyright © 2011-2022 走看看