[BZOJ1672]&&[Usaco2005 Dec]Cleaning Shifts 清理牛棚

描述 Description

Farmer John’s cows, pampered since birth, have reached new heights of fastidiousness. They now require their barn to be immaculate. Farmer John, the most obliging of farmers, has no choice but hire some of the cows to clean the barn. Farmer John has N (1 <= N <= 10,000) cows who are willing to do some cleaning. Because dust falls continuously, the cows require that the farm be continuously cleaned during the workday, which runs from second number M to second number E during the day (0 <= M <= E <= 86,399). Note that the total number of seconds during which cleaning is to take place is E-M+1. During any given second M..E, at least one cow must be cleaning. Each cow has submitted a job application indicating her willingness to work during a certain interval T1..T2 (where M <= T1 <= T2 <= E) for a certain salary of S (where 0 <= S <= 500,000). Note that a cow who indicated the interval 10..20 would work for 11 seconds, not 10. Farmer John must either accept or reject each individual application; he may NOT ask a cow to work only a fraction of the time it indicated and receive a corresponding fraction of the salary. Find a schedule in which every second of the workday is covered by at least one cow and which minimizes the total salary that goes to the cows.

约翰的奶牛们从小娇生惯养,她们无法容忍牛棚里的任何脏东西.约翰发现,如果要使这群有洁癖的奶牛满意,他不得不雇佣她们中的一些来清扫牛棚, 约翰的奶牛中有 N(1≤N≤10000) 头愿意通过清扫牛棚来挣一些零花钱.由于在某个时段中奶牛们会在牛棚里随时随地地乱扔垃圾,自然地,她们要求在这段时间里,无论什么时候至少要有一头奶牛正在打扫.需要打扫的时段从某一天的第 M 秒开始,到第 E 秒结束 f0≤M≤E≤86399).注意这里的秒是指时间段而不是时间点,也就是说,每天需要打扫的总时间是 E-M+I 秒. 约翰已经从每头牛那里得到了她们愿意接受的工作计划:对于某一头牛,她每天都愿意在笫 Ti,.T2 秒的时间段内工作 (M≤Ti≤马≤E),所要求的报酬是 S 美元 (0≤S≤500000).与需打扫时段的描述一样,如果一头奶牛愿意工作的时段是每天的第 10_20 秒,那她总共工作的时间是 11 秒,而不是 10 秒.约翰一旦决定雇佣某一头奶牛,就必须付给她全额的工资,而不能只让她工作一段时间,然后再按这段时间在她愿意工作的总时间中所占的百分比来决定她的工资.现在请你帮约翰决定该雇佣哪些奶牛以保持牛棚的清洁,当然,在能让奶牛们满意的前提下,约翰希望使总花费尽量小.

输入格式 InputFormat

Line 1: Three space-separated integers: N, M, and E.

Lines 2..N+1: Line i+1 describes cow i’s schedule with three space-separated integers: T1, T2, and S.

第 1 行:3 个正整数 N,M,E,用空格隔开.

第 2 到 N+1 行:第 i+l 行给出了编号为 i 的奶牛的工作计划,即 3 个用空格隔开的正整数 Ti,T2,S.

输出格式 OutputFormat

Line 1: a single integer that is either the minimum total salary to get the barn cleaned or else -1 if it is impossible to clean the barn.

输出一个整数,表示约翰需要为牛棚清理工作支付的最少费用.如果清理工作不可能完成,那么输出 - 1.

样例输入 SampleInput

5 0 4
2 2 2
1 1 1
4 4 4
0 0 0
3 3 3

样例输出 SampleOutput

10


BZOJ 1672


代码 Code

线段树。但因为时限 5s,所以可以用 O(n^2) 的 dp 水过。。。

#include <stdio.h>
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
const int inf=0x7fffffff/27.11;
int i,j,t,n,m,l,r,k,z,y,x;
inline void read(int &x)
{
    int k=1;x=0;char ch=getchar();
    for (;ch<'0' || ch>'9';ch=getchar()) if (ch=='-') k=-1;
    for (;ch>='0' && ch<='9';ch=getchar()) x=x*10+ch-'0';
    x*=k;
}
struct cow
{
    int ts,te,s;
    bool operator < (const cow& tmp) const
    {
        return (ts!=tmp.ts)?(ts<tmp.ts):((te!=tmp.te)?(te<tmp.te):(s<tmp.s));
    }
}a[10005];
int e;
int f[10005];
int ans;
int main()
{
    read(n);read(m);read(e);
    for (i=1;i<=n;i++) read(a[i].ts),read(a[i].te),read(a[i].s);
    sort(a+1,a+n+1);
    ans=inf;
    for (i=1;i<=n;i++) f[i]=inf;
    for (i=1;i<=n;i++) if (a[i].ts<=m) f[i]=a[i].s;
    for (i=2;i<=n;i++) for (j=1;j<i;j++) if (a[j].te>=a[i].ts-1)
    {
        f[i]=min(f[i],f[j]+a[i].s);
        if (a[i].te>=e) ans=min(ans,f[i]);
    }
    ans=(ans==inf)?-1:ans;
    printf("%d\n",ans);
    return 0;
}