P4644 [USACO05DEC]Cleaning Shifts S(线段树维护DP)

  • 将目标区间[m,e]转换为[1,e-m+1],同时转换每个奶牛的工作区间。
  • dp[i]表示覆盖区间[1,i]所需最小代价,dp[T2]=min(dp[i]+s),T1-1<=i<=T2-1。
  • 状态转移方程涉及区间查询最小值,因此可以丢进线段树维护。时间复杂度O(ne)降至O(nloge)。
  • 初始将cow按T2从小到大排序,segmenttree[0,0]=0。
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <queue>
using namespace std;
const int maxn=10005,maxm=88000;
int n,m,e;
long long tree[maxm*4];
struct cow{
    int lef,rig,cos;
    bool operator<(const cow &a)const{
        return lef<a.lef;
    }
}c[maxn];
bool cmp(cow a,cow b)
{
    return a.rig<b.rig;
}
void pushup(int x,int l,int r)
{
    tree[x]=min(tree[x<<1],tree[x<<1|1]);
}
void inserts(int x,int l,int r,int ll,int rr,long long k)
{
    if(r<ll||l>rr) return ;
    if(l>=ll&&r<=rr)
    {
        tree[x]=min(k,tree[x]);
        return;
    }
    int mid=(l+r)>>1;
    inserts(x<<1,l,mid,ll,rr,k);
    inserts(x<<1|1,mid+1,r,ll,rr,k);
    pushup(x,l,r);
}
long long query(int x,int l,int r,int ll,int rr)
{
    if(r<ll||l>rr) return 1e10;
    if(l>=ll&&r<=rr)
        return tree[x];
    int mid=(l+r)>>1;
    return min(query(x<<1,l,mid,ll,rr),query(x<<1|1,mid+1,r,ll,rr));
}
int main()
{
    for(int i=1;i<=4*maxm-1;i++) tree[i]=1e10;
    scanf("%d%d%d",&n,&m,&e);
    e-=(m-1);
    for(int i=1;i<=n;i++)
    {
        scanf("%d%d%d",&c[i].lef,&c[i].rig,&c[i].cos);
        c[i].lef-=(m-1);
        c[i].rig-=(m-1);
    }
    sort(c+1,c+1+n,cmp);
    inserts(1,0,e,0,0,0);
    for(int i=1;i<=n;i++)
    {
        long long ans=query(1,0,e,c[i].lef-1,c[i].rig-1);
        if(ans==1e10) continue;//意味着使用奶牛i不能覆盖1--i,同时意味着i不会产生贡献。
        inserts(1,0,e,c[i].rig,c[i].rig,ans+c[i].cos);
    }
    cout<<(query(1,0,e,e,e)==1e10?-1:query(1,0,e,e,e));
    return 0;
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

哈希表扁豆

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值