zoukankan      html  css  js  c++  java
  • BZOJ1109 [POI2007]堆积木Klo

    第一眼看出是动态规划。

    然后写方程:令f[i]表示下面i个积木里面必须取第i个的情况下满足要求的最多个数。

    则f[i] = max(f[j] + 1)

    其中j满足以下三个条件

    (1) j < i

    (2) a[j] < a[i]

    (3) a[i] - a[j] <= i - j

    把(3)变形:a[i] - i <= a[j] - j ......(4)

    这时ZYH神犇告诉我(2) + (3)可以推出(1),即只需满足(2)、(4)两个条件即可

    于是得到方法了:先排序(第一关键字a[i] - i升序,第二关键字a[i]降序),然后直接求新数列的LIS即可。

    其实这里求LIS时,每次要求[1, i]的最大值,不需要线段树维护,只要树状数组就可以了。

     1 /**************************************************************
     2     Problem: 1109
     3     User: rausen
     4     Language: C++
     5     Result: Accepted
     6     Time:332 ms
     7     Memory:3148 kb
     8 ****************************************************************/
     9  
    10 #include <cstdio>
    11 #include <cmath>
    12 #include <algorithm>
    13  
    14 using namespace std;
    15  
    16 struct Rec{
    17     int num, x;
    18 } a[150000];
    19 int ans, n, f[150000], Bit[150000];
    20  
    21 bool cmp(Rec a, Rec b){
    22     return a.x == b.x ? a.num < b.num : a.x > b.x;
    23 } 
    24  
    25 inline int lowbit(int x){
    26     return x & (-x);
    27 }
    28  
    29 int query(int x){
    30     if (!x) return 0;
    31     int res = 0;
    32     while (x){
    33         res = max(res, Bit[x]);
    34         x -= lowbit(x);
    35     }
    36     return res;
    37 }
    38  
    39 void add(int x, int y){
    40     while (x <= n){
    41         Bit[x] = max(Bit[x], y);
    42         x += lowbit(x);
    43     }
    44 }
    45  
    46 int main(){
    47     scanf("%d", &n);
    48     for (int i = 1; i <= n; ++i){
    49         scanf("%d", &a[i].num);
    50         a[i].x = a[i].num - i;
    51     }
    52     sort(a + 1, a + n + 1, cmp);
    53      
    54     for (int i = 1; i <= n; ++i){
    55         if (a[i].x > 0) continue;
    56         int X = query(a[i].num - 1);
    57         f[i] = X + 1;
    58         ans = max(ans, f[i]);
    59         add(a[i].num, f[i]);
    60     }       
    61     printf("%d
    ", ans);
    62     return 0;
    63 }
    View Code


     

    By Xs酱~ 转载请说明 博客地址:http://www.cnblogs.com/rausen
  • 相关阅读:
    Postgresql
    Partitioning with PostgreSQL v11 (转发)
    Partitioning with PostgreSQL v11 (转发)
    What is Data Partitioning?(转发)(未完待续)
    How to use table partitioning to scale PostgreSQL(转发)
    PostgreSQL 创建分区表(转发)
    json vs jsonb
    性能不佳的多线程应用程序的常见模式(microsoft)
    提高.net程序性能和稳定性-CLR Profile(转发)
    检查c#代码内存泄露工具-CLR Profiler工具使用(转发)
  • 原文地址:https://www.cnblogs.com/rausen/p/4001609.html
Copyright © 2011-2022 走看看