• 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

  • 相关阅读:
    更换笔记本电脑记录数据迁移过程
    solaris下的目录ls不到,却能cd进去
    轻松掌握ORACLE 11GR2的RAC实施
    魏公村口腔医院挂号
    springstrutshibernate学习
    oracle RAC启动序列
    HPUX内存监控
    DOM操作 vs. innerHTML
    oracle导入导出技巧
    jQuery幻灯片带缩略图平移滑动焦点图
  • 原文地址:https://www.cnblogs.com/wonderzy/p/3434269.html
Copyright © 2020-2023  润新知