• HDU 4719Oh My Holy FFF 线段树+DP


    /*
    **  日期: 2013-9-12
    **  题目大意:有n个数,划分为多个部分,假设M份,每份不能多于L个。每个数有一个h[i],
    **  每份最右边的那个数要大于前一份最右边的那个数。设每份最右边的数为b[i],
    **  求最大的sum{b[i]² - b[i - 1]},1≤i≤M,其中b[0] = 0。
    **  思路:朴素DP为,dp[i]表示以i为结尾的最大划分。那么dp[i] = max{dp[j] - h[j] + h[i]²},
    **  1≤i-j≤L,h[j]<h[i]。这种会超时,采取线段树优化。因为有两个限制,考虑到若h[j]≥h[i],
    **  那么求i的时候一定不会用到j,那么先按h排序再DP(h相同的,i大的排前面)。
    **  __int64 没改完,导致wa了无数次
    */
    
    
    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #define lson rt<<1,left,m
    #define rson rt<<1|1,m+1,right
    #define mid  (left+right)>>1
    using namespace std;
    
    typedef __int64 LL ;
    const int maxn = 100005;
    LL maxt[maxn<<2];
    int L,n;
    struct node{
        int pos;LL h;
        node(int id = 0,LL hight = 0):pos(id),h(hight){}
        bool operator < (node a)const{
            if( h == a.h)return pos > a.pos;
            return h < a.h;
        }
    }arr[maxn];
    void update(int rt,int left,int right,int place,LL val){
        if( left == right){
            maxt[rt] = val;
            return ;
        }
        int m = mid;
        if( place <= m)update(lson,place,val);
        else update(rson,place,val);
        maxt[rt] = max(maxt[rt<<1],maxt[rt<<1|1]);
    }
    LL query(int rt,int left,int right,int l,int r){
        if( left >= l && right <= r){
            return maxt[rt];
        }
        int m = mid;
        LL res = -1;
        if( l <= m)res = max(res,query(lson,l,r));
        if( r > m )res = max(res,query(rson,l,r));
        return res;
    }
    LL solve(){
        sort(arr,arr+n);
        LL res = -1;
        memset(maxt,-1,sizeof(maxt));
        update(1,0,n,0,0);
        for(int i = 0; i < n; i++){
            LL tmp = query(1,0,n,max(arr[i].pos-L,0),arr[i].pos - 1);
            if( tmp == -1 ){
                if( arr[i].pos == n)return -1;
                continue;
            }
            res = tmp + (LL)arr[i].h*arr[i].h;
            if( arr[i].pos == n)return res;
            update(1,0,n,arr[i].pos,res - arr[i].h);
        }
        return res;
    }
    int main(){
        int t,cas = 1;LL h;
        scanf("%d",&t);
        while( t-- ){
            scanf("%d%d",&n,&L);
            for(int i = 0; i < n; i++){
                scanf("%I64d",&h);
                arr[i] = node(i+1,h);
            }
            LL ans = solve();
            printf("Case #%d: ",cas++);
            if( ans == -1)puts("No solution");
            else printf("%I64d
    ",ans);
        }
        return 0;
    }
    
  • 相关阅读:
    Windows 8 Developer Preview 已经开始提供下载!!!
    5 款傻瓜式手机 APP 开发工具
    25 超棒的 HTML5 Canvas 游戏
    12 个免费在线的 Web 网站性能测试工具
    13 个强大的基于 HTML5 的 Web 应用
    《美国毒枭》的“大悔”与“大爱”
    WEB资源大全
    5 款基于 Web 浏览器的建模工具
    iPhone开发网站
    ios开发心得之一
  • 原文地址:https://www.cnblogs.com/LUO257316/p/3317012.html
Copyright © 2020-2023  润新知