P4644 Cleaning Shifts S (线段树+动态规划)

P4644 Cleaning Shifts S (线段树+动态规划)

题目传送门

题意简介

使用 \(n\)\([L,R]\) 的区间完全覆盖 \([M,E]\) 的线段,求使用区间最小花费和

思路

考虑 \(dp_i\) 表示覆盖 \([M,i]\) 的最小花费,将区间按照右端点升序排列后,对于第 \(k\) 条区间, \(dp_{R[k]}\) = \(min\) \((\)\(dp_x\)\()\) \(+\) \(Cost_i\),其中 \(x\) \(\in\) \([L_i,R_i]\) ,使用线段树维护区间最小值,每次求得 \(R_i\) 上的 \(dp\) 值后进行修改

Code

#include<iostream>
#include<algorithm>
#include<cstring>
#define IOS ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
using namespace std;
const int N=9e4+5;
const int M=1e4+5;
struct Data
{
    int st,ed;
    long long cost;
}cow[M];
int n,L,R;
long long dp[N];
struct SegmentTree
{
    struct node
    {
        int l,r;
        long long minn;
    }Tree[N<<2];
    long long lazy[N<<2];
    void pushup(int k)
    {
        Tree[k].minn=min(Tree[k<<1].minn,Tree[k<<1|1].minn);
    }
    void pushdown(int k)
    {
        if(!lazy[k]) return;
        lazy[k<<1]=lazy[k];
        Tree[k<<1].minn=lazy[k];
        lazy[k<<1|1]=lazy[k];
        Tree[k<<1|1].minn=lazy[k];
        lazy[k]=0;
    }
    void buildtree(int k,int L,int R)
    {
        Tree[k].l=L,Tree[k].r=R;
        if(L==R)
        {
            Tree[k].minn=dp[L];
            return;
        }
        int Mid=(L+R)>>1;
        buildtree(k<<1,L,Mid);
        buildtree(k<<1|1,Mid+1,R);
        pushup(k);
    }
    void modify(int k,int L,int R,long long val)
    {
        if(L<=Tree[k].l&&Tree[k].r<=R)
        {
            Tree[k].minn=val;
            lazy[k]=val;
            return;
        }
        pushdown(k);
        if(L<=Tree[k<<1].r)
            modify(k<<1,L,R,val);
        if(R>=Tree[k<<1|1].l)
            modify(k<<1|1,L,R,val);
        pushup(k);
    }
    long long query(int k,int L,int R)
    {
        if(L<=Tree[k].l&&Tree[k].r<=R)
            return Tree[k].minn;
        long long res=0x3f3f3f3f3f3f3f3f;
        if(L<=Tree[k<<1].r)
            res=min(res,query(k<<1,L,R));
        if(R>=Tree[k<<1|1].l)
            res=min(res,query(k<<1|1,L,R));
        return res;
    }
}Segment;
bool cmp(Data x,Data y)
{
    return x.ed<y.ed;
}
int main()
{
    IOS;
    cin>>n>>L>>R;
    for(int i=1;i<=n;i++)
        cin>>cow[i].st>>cow[i].ed>>cow[i].cost;
    sort(cow+1,cow+n+1,cmp);
    for(int i=0;i<N;i++)
        dp[i]=0x3f3f3f3f3f3f3f3f;
    dp[L-1]=0;//注意不能直接将起点处赋值为0
    Segment.buildtree(1,L-1,R);
    for(int i=1;i<=n;i++)
    {
        dp[cow[i].ed]=min(dp[cow[i].ed],Segment.query(1,cow[i].st-1,cow[i].ed)+cow[i].cost);
        Segment.modify(1,cow[i].ed,cow[i].ed,dp[cow[i].ed]);
    }
    cout<<(Segment.query(1,R,R)>=0x3f3f3f3f3f3f3f3f?-1:Segment.query(1,R,R))<<'\n';
    return 0;
}

完结撒花~

posted @ 2025-07-30 10:12  FallingGardenia  阅读(10)  评论(0)    收藏  举报