程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> POJ 3171(區間覆蓋最小代價)

POJ 3171(區間覆蓋最小代價)

編輯:C++入門知識


Language:
Cleaning Shifts
Time Limit: 1000MS   Memory Limit: 65536K
Total Submissions: 2093   Accepted: 735
Description
有N (1 <= N <= 10,000)個區間,求覆蓋[M,E](0 <= M <= E <= 86,399)的最小代價.
每個區間的代價為S (where 0 <= S <= 500,000).

Input
第一行3個整數: N, M, E.

第二行到第n+1行,每行3個數,分別表示第i-1個區間的左端點T1,右端點T2,和代價S.
Output www.2cto.com
僅一行表示最小代價,無解輸-1.
Sample Input
3 0 4
0 2 3
3 4 2
0 0 1
Sample Output
5
Hint
樣例解釋
取第一個和第二個區間。
Source
USACO 2005 December Silver
這題是一個Dp問題,先列出Dp方程。
F[i]表示取[M,i]這個區間的代價
顯然F[M-1]=0,答案就是F[E]
則方程為F[a[i].T2]=min(F[j])+a[i].S (T1-1<=J<=T2-1)
a[i]按T2從小到大排列;
那麼顯然a[i]取時,[M,T1-1]已經被前面的給取了,
因為如果被後面的[t1,t2] 取了,那麼必有t1<T1 T2<t2, 就沒必要取[T1,T2]了。

取最小的數可以用線段樹做O(NlogN)。

[cpp]
#include<cstdio> 
#include<cstring> 
#include<cstdlib> 
#include<cmath> 
#include<cctype> 
#include<iostream> 
#include<functional> 
#include<algorithm> 
using namespace std; 
#define MAXN (10000+10) 
#define MAXE (86399) 
#define MAXS (500000+10) 
#define INF (9187201950435737471) 
int n,s,e; 
struct SegMent 

    int l,r; 
    long long S; 
    SegMent(){} 
    SegMent(int _l,int _r,long long _S):l(_l),r(_r),S(_S){} 
    friend bool operator<(const SegMent a,const SegMent b){return a.r<b.r;} 
}a[MAXN]; 
struct SegMentTree //min() 

    int n,M; 
    long long t[MAXE*10]; 
    void fillchar(int _n) 
    { 
        n=_n+2; 
        M=1;while (M-2<n) M<<=1; 
        memset(t,127,sizeof(t)); 
    } 
    void update(int x) 
    { 
        for (x>>=1;x;x>>=1) t[x]=min(t[x<<1],t[(x<<1)^1]); 
    } 
    void insert(int x,long long c) 
    { 
        x=x+2; 
        x+=M; 
        if (t[x]>c) {t[x]=c; update(x);  } 
    } 
    long long find(int l,int r) 
    { 
        l=l+2;r=r+2; 
                 
        l=l-1+M;r=r+1+M; 
        long long ans=INF; 
        while (l^r^1) 
        { 
            if (~l&1) ans=min(ans,t[l+1]); 
            if (r&1) ans=min(ans,t[r-1]); 
            l>>=1;r>>=1; 
        } 
        return ans; 
    } 
}t; 
int main() 

//  freopen("poj3171.in","r",stdin); 
    scanf("%d%d%d",&n,&s,&e); 
    for (int i=1;i<=n;i++) scanf("%d%d%d",&a[i].l,&a[i].r,&a[i].S); 
    sort(a+1,a+1+n); 
    t.fillchar(e); 
    t.insert(s-1,0); 
    for (int i=1;i<=n;i++) 
    { 
        if (a[i].r<s) continue; 
        t.insert(a[i].r,t.find(max(s-1,a[i].l-1),a[i].r-1)+a[i].S); 
    }    
/*  for (int i=t.M;i<=t.M*2;i++) cout<<t.t[i]<<' ';
    cout<<endl;
*/  if (t.t[e+2+t.M]==INF) cout<<"-1\n"; 
    else cout<<t.t[e+2+t.M]<<endl;   
     
     
    return 0; 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved