您的位置:首页 > 其它

USACO 2005 Cleaning Shifts 带权区间调度、覆盖问题 单调栈优化dp

2016-03-27 13:01 701 查看
首先,根据区间右端点从小到大的顺序对区间排序,之后以区间为阶段进行线性动归。

dp[x]的意义是第x个区间为最后一个区间,从开始时间到a[x].ri这段时间的最小花费。

计算dp[x]的时候,是找一个前面存在的p,使得   a[x].le -1<=p  且dp[p]最小。

根据计算的顺序,维护一个只入队,不出队的单调递增队列,配合二分查找 即可快速完成 查找最优解的任务。

时间复杂度O(n*logn)+O(n*logn)=O(n*logn) 。

实际上就是单调栈。

Cleaning Shifts

Time Limit: 1000MS Memory Limit: 65536K
Total Submissions: 3144 Accepted: 1067
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.
Input

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.
Output

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.
Sample Input
3 0 4
0 2 3
3 4 2
0 0 1

Sample Output
5

Hint

Explanation of the sample: 

FJ has three cows, and the barn needs to be cleaned from second 0 to second 4. The first cow is willing to work during seconds 0, 1, and 2 for a total salary of 3, etc. 

Farmer John can hire the first two cows.
Source

USACO 2005 December Silver

#include<cstdio>
#include<string>
#include<cstring>
#include<iostream>
#include<cmath>
#include<algorithm>
using namespace std;
typedef long long ll;
const ll inf =1e15;
const int maxn= 10000   ;
int n,st,ed;

ll dp[maxn+10];
struct Seg
{
int le,ri; ll cost;
bool operator<(const Seg y)const
{
return ri<y.ri;
}
} a[maxn+5];

int bs(int le,int ri,int x);

struct myQueue
{
int rear,front;
int q[maxn+5];
void clear()
{
rear=1,front=0;
}
bool empty()
{
return rear==front;
}

int query(int  x)
{
if(empty()) return -1;
int p=bs(front,rear-1,x);

return p==rear?-1:q[p];
}
void insert(int ind)
{
while(front<rear&& dp[ q[rear-1] ]>=dp[ind] )
{
rear--;
}
q[rear++]=ind;
}

}Q;

int bs(int le,int ri,int x)
{
while(le<=ri)
{
int mid=(le+ri)>>1;
int  real=Q.q[mid];
if( a[real].ri>= x )  ri=mid-1;
else le=mid+1;
}
return le;
}
void work()
{

Q.clear();

dp[0]=0;
Q.insert(0);

for(int i=1 ;i<=n;i++)
{

Seg &now=a[i];
int ri=now.ri;
int le=now.le;
ll cost=now.cost;

int p=Q.query( le-1);

if(p==-1)    dp[i]=-1;
else
{
dp[i]=cost+dp[p];

Q.insert(i);
}
}
ll ans=inf;
for(int i=1;i<=n;i++) if(a[i].ri>=ed&& ~dp[i])
{
ans=min(ans,dp[i]);
}
if(ans==inf) {puts("-1");return;}
printf("%lld\n",ans);

}
int main()
{
while(~scanf("%d%d%d",&n,&st,&ed))
{
for(int i=1;i<=n;i++)
{
scanf("%d%d%lld",&a[i].le,&a[i].ri,&a[i].cost);
}
sort(a+1,a+1+n);

a[0].le=a[0].ri=st-1;
a[0].cost=0;

if(a
.ri<ed)  {puts("-1");continue;}
work();
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: