zoukankan      html  css  js  c++  java
  • [USACO2012 OPEN] Bookshelf

    [题目链接]

             https://www.lydsy.com/JudgeOnline/problem.php?id=2678

    [算法]

             首先不难想到如下DP :

             记f[i]表示前i本书的高度和最小值

             显然 , 有状态转移方程 : f[i] = min{ fj + max{hj+1 , hj+2 , ... hi} }

             不难发现 , 当i确定时 , 随着j的减小 , max{hj + 1 , hj+2 , ... hi}的值单调递增

             不妨维护一个单调递减的单调栈

             预处理前缀和 , 每次在单调栈中二分出最靠左的左端点 

             然后 , 我们还需维护一棵支持单点修改 , 区间查询的线段树

             每次在线段树中找到从合法左端点到当前点的最小值

             详见代码 , 时间复杂度 : O(NlogN)

    #include<bits/stdc++.h>
    using namespace std;
    #define MAXN 100010
    typedef long long LL;
    const LL inf = 1e18;
    
    struct info
    {
        LL h , w;
    } a[MAXN];
    
    LL n , top;
    LL L;
    int s[MAXN];
    LL cnt[MAXN] , dp[MAXN];
    
    struct Segment_Tree
    {
        struct Node
        {
            int l , r;
            LL mn;    
        } Tree[MAXN << 2];
        inline void build(int index , int l , int r)
        {
            Tree[index] = (Node){l , r , inf};
            if (l == r) return;
            int mid = (l + r) >> 1;
            build(index << 1 , l , mid);
            build(index << 1 | 1 , mid + 1 , r); 
        }
        inline void update(int index)
        {
            Tree[index].mn = min(Tree[index << 1].mn , Tree[index << 1 | 1].mn);
        }
        inline void modify(int index , int pos , LL value)
        {
            if (Tree[index].l == Tree[index].r)
            {
                Tree[index].mn = value;
                return;
            }
            int mid = (Tree[index].l + Tree[index].r) >> 1;
            if (mid >= pos) modify(index << 1 , pos , value);
            else modify(index << 1 | 1 , pos , value);
            update(index);
        }
        inline LL query(int index , int l , int r)
        {
            if (l > r) return inf;
            if (Tree[index].l == l && Tree[index].r == r) return Tree[index].mn;
            int mid = (Tree[index].l + Tree[index].r) >> 1;
            if (mid >= r) return query(index << 1 , l , r);
            else if (mid + 1 <= l) return query(index << 1 | 1 , l , r);
            else return min(query(index << 1 , l , mid) , query(index << 1 | 1 , mid + 1 , r));
        }
    } SGT;
    
    template <typename T> inline void chkmax(T &x , T y) { x = max(x , y); }
    template <typename T> inline void chkmin(T &x , T y) { x = min(x , y); }
    template <typename T> inline void read(T &x)
    {
        T f = 1; x = 0;
        char c = getchar();
        for (; !isdigit(c); c = getchar()) if (c == '-') f = -f;
        for (; isdigit(c); c = getchar()) x = (x << 3) + (x << 1) + c - '0';
        x *= f;
    }
    
    int main()
    {
        
        read(n); read(L);
        for (int i = 1; i <= n; i++)
        {
            read(a[i].h);
            read(a[i].w);
            cnt[i] = cnt[i - 1] + a[i].w;
        }
        SGT.build(1 , 1 , n + 1);
        s[top = 1] = 0; 
        dp[0] = s[0] = 0;
        SGT.modify(1 , 1 , 0);
        for (int i = 1; i <= n; i++)
        {
            while (top > 0 && a[i].h > a[s[top]].h) --top;
            s[++top] = i;
            SGT.modify(1 , top , dp[s[top - 1]] + a[i].h);
            int l = 1 , r = top , pos = 0;
            while (l <= r)
            {
                int mid = (l + r) >> 1;
                if (cnt[i] - cnt[s[mid]] <= L)
                {
                    pos = mid;
                    r = mid - 1;
                } else l = mid + 1;
            }
            int loc = lower_bound(cnt , cnt + n + 1 , cnt[i] - L) - cnt;
            dp[i] = SGT.query(1 , pos + 1 , top);
            chkmin(dp[i] , dp[loc] + a[s[pos]].h);
        }
        cout<< dp[n] << '
    ';
        
        return 0;
    }

            

  • 相关阅读:
    poj-2888-矩阵+polya
    hdu-2865-polya+dp+矩阵+euler函数
    poj-2154-polya+euler函数
    poj-1026-置换
    poj-2369-置换
    2017.2.15 开涛shiro教程-第二十一章-授予身份与切换身份(二) controller
    2017.2.13 开涛shiro教程-第十二章-与Spring集成(二)shiro权限注解
    2017.2.13 开涛shiro教程-第十二章-与Spring集成(一)配置文件详解
    2017.2.12 开涛shiro教程-第八章-拦截器机制
    2017.2.12 开涛shiro教程-第七章-与Web集成
  • 原文地址:https://www.cnblogs.com/evenbao/p/9925900.html
Copyright © 2011-2022 走看看