zoukankan      html  css  js  c++  java
  • [POJ1631]Bridging signals (DP,二分优化)

    题目链接:http://poj.org/problem?id=1631

      就是求一个LIS,但是范围太大(n≤40000),无法用常规O(n²)的朴素DP算法,这时需要优化。

      新加一个数组s[]来维护长度当LIS的长度为len时候需要的数组a中的最小数字的值,可以证明这个数组是严格单调递增的,因此可以二分确定每次枚举到a[i]的时候,a[i]在这个数组中所处的位置(下标),也就是a[i]数字时此时之前算过的LIS的长度。之后更新s数组和ans即可。对于最长下降自序列此方法同样适用,但是需要注意那时s数组是严格单调递减的,并且更新s数组的时候也要尽可能地取大值。

     1 #include <algorithm>
     2 #include <iostream>
     3 #include <iomanip>
     4 #include <cstring>
     5 #include <climits>
     6 #include <complex>
     7 #include <fstream>
     8 #include <cassert>
     9 #include <cstdio>
    10 #include <bitset>
    11 #include <vector>
    12 #include <deque>
    13 #include <queue>
    14 #include <stack>
    15 #include <ctime>
    16 #include <set>
    17 #include <map>
    18 #include <cmath>
    19 
    20 using namespace std;
    21 
    22 const int maxn = 40010;
    23 int n;
    24 int dp[maxn];
    25 int s[maxn];
    26 int a[maxn];
    27 
    28 int bs(int ll, int rr, int v) {
    29     while(ll <= rr) {
    30         int mm = (ll + rr) >> 1;
    31         if(s[mm] <= v) ll = mm + 1;
    32         else rr = mm - 1;
    33     }
    34     return ll;
    35 }
    36 
    37 int main() {
    38     // freopen("in", "r", stdin);
    39     int T;
    40     scanf("%d", &T);
    41     while(T--) {
    42         scanf("%d", &n);
    43         for(int i = 1; i <= n; i++) {
    44             scanf("%d", &a[i]);
    45         }
    46         memset(dp, 0, sizeof(dp));
    47         memset(s, 0x7f7f7f7f, sizeof(s));
    48         // for(int i = 1; i <= n; i++) {
    49         //     dp[i] = 1;
    50         //     for(int j = 1; j < i; j++) {
    51         //         if(a[i] > a[j] && dp[i] < dp[j] + 1) {
    52         //             dp[i] = dp[j] + 1;
    53         //         }
    54         //     }
    55         //     ans = max(dp[i], ans);
    56         // }
    57         int ans = 0;
    58         for(int i = 1; i <= n; i++) {
    59             dp[i] = bs(1, i, a[i]);
    60             printf("%d ", dp[i]);
    61             s[dp[i]] = min(s[dp[i]], a[i]);
    62             ans = max(ans, dp[i]);
    63         }
    64         printf("
    ");
    65         printf("%d
    ", ans);
    66     }
    67     return 0;
    68 }
  • 相关阅读:
    设计模式--22、状态模式
    设计模式--21、备忘录模式
    设计模式--20、迭代器模式
    关于分布式事务、两阶段提交协议、三阶提交协议
    分布式系统的一致性探讨
    分布式系统的BASE理论
    分布式系统的CAP理论
    Kafka集群环境搭建
    Elasticsearch插件head的安装(有坑)
    centos6 x64安装elasticsearch5.5.2启动报错
  • 原文地址:https://www.cnblogs.com/kirai/p/5398350.html
Copyright © 2011-2022 走看看