Description
A supermarket has a set Prod of products on sale. It earns a profit px for each product x∈Prod sold by a deadline dx that is measured as an integral number of time units starting from the moment the sale begins. Each product takes precisely one unit of time for being sold. A selling schedule is an ordered subset of products Sell ≤ Prod such that the selling of each product x∈Sell, according to the ordering of Sell, completes before the deadline dx or just when dx expires. The profit of the selling schedule is Profit(Sell)=Σx∈Sellpx. An optimal selling schedule is a schedule with a maximum profit.
For example, consider the products Prod={a,b,c,d} with (pa,da)=(50,2), (pb,db)=(10,1), (pc,dc)=(20,2), and (pd,dd)=(30,1). The possible selling schedules are listed in table 1. For instance, the schedule Sell={d,a} shows that the selling of product d starts at time 0 and ends at time 1, while the selling of product a starts at time 1 and ends at time 2. Each of these products is sold by its deadline. Sell is the optimal schedule and its profit is 80.
Write a program that reads sets of products from an input text file and computes the profit of an optimal selling schedule for each set of products.
题目大意:多组测试数据,每组n个物品,给定价值和售出期限,要求在期限之前卖出商品,同一时刻只能售出一个商品,求能得到的最大价值。
思路:看到题目就醉了。。。赤裸裸的贪心,不过O(n^2)也是醉了。。。后来明白可以用堆来优化,但不会写啊!!!我又不是xxy。于是就用并查集优化了。。。神奇!!!
我们把连续的被占用的区间看成一个集合(子树),它的根结点为这个区间左边第一个未被占用的区间。先排序,然后每次判断Find(b[i])是否大于0,大于0说明左边还有未被占用的空间,则占用它,然后合并(rool(b[i]), rool(rool(b[i]) – 1)即可。同样这里我们规定只能左边的子树合并到右边的子树。
理解了方法,code也就很出来了。。。
code:
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
using namespace std;
int fa[10001]={0};
struct use{
int va,ti;
}a[10001];
int rool(int x)
{
if (fa[x]!=x) fa[x]=rool(fa[x]);
return fa[x];
}
int my_comp(const use &x,const use &y)
{
if (x.va>y.va) return 1;
else
{
if (x.va==y.va&&x.ti<y.ti) return 1;
else return 0;
}
}
int main()
{
int n,i,j,r1,maxn;
long long ans;
while(scanf("%d",&n)==1)
{
ans=0;
maxn=0;
for (i=1;i<=n;++i)
{
scanf("%d%d",&a[i].va,&a[i].ti);
if (a[i].ti>maxn) maxn=a[i].ti;
}
for (i=1;i<=maxn;++i)
fa[i]=i;
sort(a+1,a+n+1,my_comp);
for (i=1;i<=n;++i)
{
r1=rool(a[i].ti);
if (r1>0)
{
fa[r1]=rool(r1-1);
ans=ans+a[i].va;
}
}
printf("%lld\n",ans);
}
}
(附加:codevs1052是同类的题目)