Cleaning Shifts[線段樹+DP]
阿新 • • 發佈:2018-11-23
區間覆蓋問題 , f[x]表示覆蓋L--x的最少代價
線段樹維護區間最小
//未ac但對拍過的程式碼 #include<cstdio> #include<algorithm> #define N 10050 #define M 100050 #define LL long long #define inf 1000000000000000 using namespace std; int n,L,R; LL f[M]; struct Tree{int l,r; LL val;}t[M<<2]; struct Node{int l,r,s;}a[N]; bool cmp(Node a,Node b){return a.r<b.r;} void Pushup(int x){ t[x].val = min(t[x<<1].val , t[x<<1|1].val); } void build(int x,int l,int r){ t[x].l=l , t[x].r=r; if(l==r){ if(l>=L) t[x].val = inf; return; } int mid=(l+r)>>1; build(x<<1,l,mid) , build(x<<1|1,mid+1,r); Pushup(x); } LL Quary(int x,int L,int R){ if(L<=t[x].l && t[x].r<=R) return t[x].val; int mid=(t[x].l+t[x].r)>>1; LL ans=inf; if(L<=mid) ans=min(ans,Quary(x<<1,L,R)); if(R>mid) ans=min(ans,Quary(x<<1|1,L,R)); return ans; } void Update(int x,int pos,LL val){ if(t[x].l==t[x].r){t[x].val=val;return;} int mid=(t[x].l+t[x].r)>>1; if(pos<=mid) Update(x<<1,pos,val); else Update(x<<1|1,pos,val); Pushup(x); } int main(){ scanf("%d%d%d",&n,&L,&R); for(int i=1;i<=n;i++){ scanf("%d%d%d",&a[i].l,&a[i].r,&a[i].s); if(a[i].l<L) a[i].l=L; if(a[i].r>R) a[i].r=R; } build(1,0,R); for(int i=1;i<=R;i++) f[i]=inf; sort(a+1,a+n+1,cmp); for(int i=1;i<=n;i++){ if(a[i].r<=L) continue; LL x=Quary(1,a[i].l-1,a[i].r); if(x+a[i].s < f[a[i].r]){ f[a[i].r] = x+a[i].s; Update(1,a[i].r,f[a[i].r]); } } if(f[R]==inf){printf("-1"); return 0;} printf("%lld",f[R]); return 0; }