zoukankan      html  css  js  c++  java
  • BZOJ4476 送礼物

    这道题真是有趣呀。

    其实就是一个分数规划问题,用一个二分加log来得去掉分母。

    分四种情况讨论

    1.lenth > L && num ( max ) > num ( min )

    2.lenth > L && num ( max ) < num ( min )

    3.lenth == L && num ( max ) > num ( min )

    4.lenth == L && num ( max ) < num ( min )

    1,2种情况中最大值与最小值一定在选择序列两端,设左右端点编号为i,j

    1. ( Vi - Vj ) / ( i - j + k ) = ans -> ( Vi - i * ans ) - ( Vj - j * ans ) = k * ans

    二分ans并check左式最大值是否大于右式

    2.( Vj - Vi ) / ( i - j + k ) = ans -> ( Vj + j * ans ) - ( Vi + i * ans ) = k * ans

    同情况1

    3,4用单调队列for一遍就可以了

      1 #include<cstdio>
      2 #include<algorithm>
      3 #include<cassert>
      4 //#define DEBUG
      5 using namespace std ; 
      6 
      7 const int MAXN = 5 * 100000 + 20 ;
      8 int N , K , L , R ; 
      9 long long a [ MAXN ] ;
     10 int p [ MAXN ] ;
     11 
     12 template < class T1 , class T2 > 
     13 void max_equal ( T1 & a , const T2 & b ) {
     14     if ( a < b ) a = b ; 
     15 }
     16 
     17 double solve1 ( const double M ) {
     18 #define f(i) (a[i]-M*(i))
     19     double ans = -1e9 ;
     20     int l = 0 , r = -1 ; 
     21     for ( int i = L ; i <= N ; ++ i ) {
     22         while ( r - l + 1 >= 1 && i - p [ l ] + 1 > R ) ++ l ;  
     23         while ( r - l + 1 >= 1 && ! ( f ( p [ r ] ) < f ( i - L + 1 ) ) ) -- r ;
     24         p [ ++ r ] = i - L + 1 ;
     25         max_equal ( ans , f ( i ) - f ( p [ l ] ) ) ;
     26     } 
     27     return ans ;
     28 #undef f 
     29 }
     30 
     31 double Solve1 () {
     32     double L = 0 , R = 1e4 ; 
     33     while ( R - L >= 1e-10 ) {
     34         const double M = ( L + R ) / 2 ; 
     35         if ( solve1 ( M ) >= K * M ) L = M ; 
     36         else R = M ; 
     37     }
     38     return ( L + R ) / 2 ; 
     39 }
     40 
     41 double solve2 ( const double M ) {
     42 #define f(i) (a[i]+M*(i))
     43     double ans = -1e9 ; 
     44     int l = 0 , r = -1 ; 
     45     for ( int i = L ; i <= N ; ++ i ) {
     46         while ( r - l + 1 >= 1 && i - p [ l ] + 1 > R ) ++ l ;
     47         while ( r - l + 1 >= 1 && ! ( f ( p [ r ] ) > f ( i - L + 1 ) ) ) -- r ; 
     48         p [ ++ r ] = i - L + 1 ; 
     49         max_equal ( ans , f ( p [ l ] ) - f ( i ) ) ; 
     50     }
     51     return ans ;
     52 #undef f
     53 }
     54 
     55 double Solve2 () {
     56     double L = 0 , R = 1e4 ; 
     57     while ( R - L >= 1e-10 ) {
     58         const double M = ( L + R ) / 2 ; 
     59         if ( solve2 ( M ) >= K * M ) L = M ; 
     60         else R = M ; 
     61     }
     62     return ( L + R ) / 2 ; 
     63 }
     64 
     65 double Solve3 () {
     66     double ans = -1e9; 
     67     int l = 0 , r = -1 ; 
     68     for ( int i = 1 ; i <= N ; ++ i ) {
     69         while ( r - l + 1 >= 1 && i - p [ l ] + 1 > L ) ++ l ;
     70         while ( r - l + 1 >= 1 && ! ( a [ p [ r ] ] < a [ i ] ) ) -- r ; 
     71         p [ ++ r ] = i ; 
     72         max_equal ( ans , a [ i ] - a [ p [ l ] ] ) ; 
     73     }
     74     return ans / ( L - 1 + K ) ;
     75 }
     76 
     77 double Solve4 () {
     78     double ans = -1e9; 
     79     int l = 0 , r = -1 ; 
     80     for ( int i = 1 ; i <= N ; ++ i ) {
     81         while ( r - l + 1 >= 1 && i - p [ l ] + 1 > L ) ++ l ;
     82         while ( r - l + 1 >= 1 && ! ( a [ p [ r ] ] > a [ i ] ) ) -- r ; 
     83         p [ ++ r ] = i ; 
     84         max_equal ( ans , a [ p [ l ] ] - a [ i ] ) ; 
     85     }
     86     return ans / ( L - 1 + K ) ;
     87 }
     88 
     89 double solve () {
     90     scanf ( "%d%d%d%d" , & N , & K , & L , & R ) ; 
     91     for ( int i = 1 ; i <= N ; ++ i ) scanf ( "%lld" , & a [ i ] ) ;
     92     return max ( max ( Solve1 () , Solve2 () ) , max ( Solve3 () , Solve4 () ) ) ;
     93 }
     94 
     95 int main () {
     96     int T ; 
     97     scanf ( "%d" , & T ) ; 
     98     while ( T -- ) printf ( "%.4lf
    " , solve () ) ; 
     99     return 0 ; 
    100 }
  • 相关阅读:
    自定义Behavior 实现Listbox自动滚动到选中项
    MVVM RelayCommand 进阶技巧 CanExcute 的使用
    通过ListItem找到相应控件
    使用VS2010调试WPF/SL/WP7设计器界面异常
    代码管理技巧——两步创建本地SVN服务器图文教程
    基于云的商务智能应该注意的事项
    双击不能打开Qlikview的解决办法
    上海天善商业智能BI培训~第四季
    上海天善商业智能培训课程安排
    用java和olap4j从SSAS中获取数据
  • 原文地址:https://www.cnblogs.com/Christopher-Cao/p/5426451.html
Copyright © 2011-2022 走看看