[Usaco2005 Dec]Cleaning Shifts

[Usaco2005 Dec]Cleaning Shifts

Segment n is given interval, the left and right end respectively \ (L_i, r_i \) , and selecting the cost of this section \ (C_i \) , now a number of selected intervals, it completely covers the interval \ ([m, e ] \) , and the cost of the minimum asking, \ (1≤n≤10000,0≤m≤e≤86399 \) .

solution

Act One:

The left end section may wish to sort out large range if the range to be screened out, although the subject is guaranteed, thus setting \ (F_i \) represents the i-th section to the end, to cover all positions to be covered before the i-th section the minimum price, so there

\ [F_i = \ min_ {j = 1, r_j + 1 \ geq l_i} ^ {i-1} \ {f_j \} + 1 \]

Border: the left point covers a large range of all manually initiated, the rest of infinity

The answer: a large section covering the right end of \ (f_i \)

Note that this is actually \ (O (n ^ 2) \) algorithm, but since n is relatively small, in fact, this is the \ (C_n ^ 2 \) , in fact, no \ (10 ^ 8 \) , so the water can be had .

Reference Code:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define il inline
#define ri register
#define intmax 16843009
using namespace std;
struct interval{
    int l,r,c;
    il bool operator<(const interval&x)const{
        return l<x.l;
    }
}I[10001];
int dp[10001];
int main(){
    int n,m,e;scanf("%d%d%d",&n,&m,&e);
    for(int i(1);i<=n;++i)
        scanf("%d%d%d",&I[i].l,&I[i].r,&I[i].c);
    sort(I+1,I+n+1),memset(dp,1,sizeof(dp));
    ri int i,j;
    for(i=1;i<=n;++i)
        if(I[i].l==m)dp[i]=I[i].c;
        else break;
    while(i<=n){
        for(j=i-1;j;--j)
            if(I[j].r+1>=I[i].l)
                if(dp[j]<dp[i])dp[i]=dp[j];
        dp[i]+=I[i].c,++i;
    }int ans(intmax);
    for(i=n;i;--i)
        if(I[i].r==e)
            if(ans>dp[i])ans=dp[i];
    if(ans<intmax)printf("%d",ans);
    else puts("-1");
    return 0;
}

Act II:

As long as people noticed the topic slightly open large data range, game over, and there are traces of water, but does not support the transfer optimization, we can only change the state, noting that if the law first, positive solutions, m, e fact can start to long long range, but m, e is very small, to enter \ (nlog ^ n \) range, it may be appreciated that the position of the state.

Thus provided \ (F_j \) so as to cover the minimum cost to the interval m j position, press the right section sorting endpoint, enumeration interval i, then there is not difficult

\[f_j=\min_{l_i-1\leq k\leq r_i-1}\{f_{k}\}+c_i\]

Border: \ (. 1-F_ {m} = 0 \) , the remaining infinity

The answer: a similar law

Every time a minimum period of notice has been obtained f we actually queried, only obtained will not be updated, so we need to query interval, so the tree or tree line array can be optimized for the \ (O (nlog ^ n) \ )

Reference Code:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define il inline
#define ri register
#define intmax 16843009
using namespace std;
il int min(int a,int b){
    return a<b?a:b; 
}
struct interval{
    int l,r,c;
    il bool operator<(const interval&x)const{
        return r<x.r;
    }
    il void read(){
        scanf("%d%d%d",&l,&r,&c),++l,++r;
    }
}I[10001];
struct segment_tree{
    int a[86400];
    struct data{
        int l,r,d;
    }t[345600];
    il void build(int p,int l,int r){
        t[p].l=l,t[p].r=r;
        if(l==r)return (void)(t[p].d=a[l]);
        int mid(l+r>>1),pl(p<<1),pr(pl|1);
        build(pl,l,mid),build(pr,mid+1,r);
        t[p].d=min(t[pl].d,t[pr].d);
    }
    il void change(int p,int x,int v){
        if(t[p].l==t[p].r)return (void)(t[p].d=v);
        int mid(t[p].l+t[p].r>>1),pl(p<<1),pr(pl|1);
        if(x<=mid)change(pl,x,v);if(x>mid)change(pr,x,v);
        t[p].d=min(t[pl].d,t[pr].d);
    }
    il int ask(int p,int l,int r){
        if(l<=t[p].l&&t[p].r<=r)return t[p].d;
        int mid(t[p].l+t[p].r>>1),pl(p<<1),pr(pl|1),ans(intmax);
        if(l<=mid)ans=min(ans,ask(pl,l,r));
        if(r>mid)ans=min(ans,ask(pr,l,r));
        return ans;
    }
}T;
int main(){
    int n,m,e,i;
    scanf("%d%d%d",&n,&m,&e),++m,++e;
    for(i=1;i<=n;++i)I[i].read();
    sort(I+1,I+n+1),memset(T.a,66,sizeof(T.a));;
    T.a[m-1]=0,T.build(1,0,e);
    for(i=1;i<=n;++i)
        T.change(1,I[i].r,min(T.ask(1,I[i].l-1,I[i].r)+I[i].c,T.ask(1,I[i].r,I[i].r)));
    int ans(T.ask(1,e,e));
    if(ans>=intmax)puts("-1");
    else printf("%d",ans);
    return 0;
}

Guess you like

Origin www.cnblogs.com/a1b3c7d9/p/10958338.html