zoukankan      html  css  js  c++  java
  • POJ 3171


    题目大意:


           给定一个区间范围[M,E],接下来有n行输入。每行输入三个数值:T1,T2,S,表示覆盖区间[T1,T2]


    的代价为S,要求你求出覆盖区间[M,E]的最小代价,假设不能覆盖,则输出-1.


    解题思路:

     

        先将区间按右端点进行排序,这样我们就能得到dp状态的定义和转移方程:

           dp[i]:表示覆盖[M,cow[i].T2]的最小覆盖代价.

           dp[i] = cow[i].cost (cow[i].l == M) 或者 dp[i] = min(dp[j~i]) + cow[i].cost(cow[j].T2 >= cow[i].T1-1)


    因为右端点可能有重合的情况,所以我们的dp[i]中可能存放的并非最小覆盖代价。当然了,


    我们能够对右端点进行离散化。然后去重,这样dp数组里面存放的就是最优解,只是这添加了


    编程的复杂度,代码量也加大不少.事实上,我们依旧能够用上述dp定义。最后dp[j~i]cow[j].T2==cow[i].T2)


    的最小值就能够了.关于dp[i] = min(dp[j~i]) + cow[i].cost,是个RMQ问题,这里我用的是线段树实现的.


    以下是解题代码。代码中对空间进行了优化。所以代码中并没有dp数组。其值都存放在线段树中.


    #include<stdio.h>
    #include<algorithm>
    #define MAX_N 11000
    #define INF 100000000000
    #define lson l,m,rt<<1
    #define rson m+1,r,rt<<1|1
    using namespace std;
    struct Node
    {
        int l,r,c;
        bool operator < (const Node &tmp) const
        {
            return r < tmp.r;
        }
    }cow[MAX_N];
    long long tree[MAX_N<<2];
    void build(int l,int r,int rt)
    {
        tree[rt] = INF ;
        if( l == r)
            return;
        int m = l + ( r - l ) / 2 ;
        build(lson);
        build(rson);
    }
    long long query(int L,int R,int l,int r,int rt)
    {
        if(L <= l && r <= R)
            return tree[rt];
        int m = l + ( r - l ) / 2 ;
        long long tmp = INF;
        if(L <= m)
            tmp = query(L,R,lson);
        if(R > m)
            tmp = min(tmp,query(L,R,rson));
        return tmp;
    }
    void update(int pos,long long val,int l,int r,int rt)
    {
        if(l == r)
        {
            tree[rt] = val ;
            return;
        }
        int m = l + ( r - l ) / 2 ;
        if(pos <= m)
            update(pos,val,lson);
        else
            update(pos,val,rson);
        tree[rt] = min(tree[rt<<1],tree[rt<<1|1]);
    }
    //去掉不满足条件的区间
    int init(int n)
    {
        int cnt = 0 , r_max = cow[0].r ;
        for(int i=1;i<n;++i)
        {
            if(cow[i].r != cow[i-1].r)
                r_max = cow[cnt].r ;
            if(cow[i].l - 1 <= r_max)
                cow[++cnt] = cow[i];
        }
        return cnt;
    }
    int Bin(int key,int l,int r)
    {
        while(l <= r)
        {
            int m = l + ( r - l ) / 2 ;
            if(cow[m].r < key)
                l = m + 1 ;
            else
                r = m - 1 ;
        }
        return l;
    }
    int main()
    {
        int n,m,e;
        while(~scanf("%d%d%d",&n,&m,&e))
        {
            int l_min = 90000 , r_max = 0 ;
            for(int i=0;i<n;++i)
            {
                scanf("%d%d%d",&cow[i].l,&cow[i].r,&cow[i].c);
                l_min = min(l_min,cow[i].l);
                r_max = max(r_max,cow[i].r);
            }
            sort(cow,cow+n);
            n = init(n) ;
            if(l_min > m || r_max < e || cow[n].r < e)
            {
                printf("-1
    ");
                continue;
            }
            build(0,n,1);
            for(int i=0;i<=n;++i)
            {
                long long tmp;
                if(cow[i].l == m)
                    tmp = (long long)cow[i].c ;
                else
                    tmp = query(Bin(cow[i].l-1,0,i),i,0,n,1) + cow[i].c;
                update(i,tmp,0,n,1);
            }
            printf("%I64d
    ",query(Bin(cow[n].r,0,n),n,0,n,1));
        }
        return 0;
    }
    



查看全文
  • 相关阅读:
    Convolution1D与Convolution2D区别
    git
    cast函数
    Ubuntu14.04编译WebRTC For Android代码 2014-07-24
    R语言基础-数组和列表
    疯狂的创业运动
    Autodesk 举办的 Revit 2015 二次开发速成( 1.5 天),教室培训, 地点武汉
    注冊(十一)重注冊带有鉴权信息
    ubuntu14.04无法安装Curl
    Bash脚本中的操作符
  • 原文地址:https://www.cnblogs.com/ldxsuanfa/p/10701100.html
  • Copyright © 2011-2022 走看看