题目链接:
https://cn.vjudge.net/problem/POJ-1456
题目大意:
有N个商品,每种保质期是di,所获得收益是pi,问所能卖出的最大收益是多少
多组测试样例
题解思路:
乍一看,这不就是个贪心题吗?最优策略都在保质期的最后一天卖,选出收益最高的卖,然后 相加不就行了嘛?但是,这样是完全错误的!不加以思考的! 假如这个样例
3 1 1 5 2 3 2 答案是多少?是8!,因为从第二天看,最高收益是5,但是3收益的可以在第一天卖!
并查集数组f[i]规定:
1.f[i]=-1 代表第i天还没有卖东西,查找时返回i
2.f[i]=i-1 代表第i天已经卖过东西了,下一个第i天保质期的只能在第i-1天卖了,查找时返回Find(f[i-1])
因此,解题思路大概出来了,首先把商品的收益从大到小排,然后查找并查集数组,
如果大于0,则卖出。
代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int MAX=-99999;
int f[10011];//并查集数组
struct G
{//商品结构体
int p,d;//p代表收益,d代表保质期
}goods[10011];
int Find(int x)
{//查找
if(f[x]==-1)
return x;
return Find(f[x]);
}
bool cmp(G g1,G g2)
{
return g1.p>g2.p;
}
int main()
{
int n,t;
while(scanf("%d",&n)!=EOF)
{
memset(f,-1,sizeof(f));
int sum=0;
memset(goods,0,sizeof(goods));
for(int i=0;i<n;i++)
{
scanf("%d%d",&goods[i].p,&goods[i].d);
}
sort(goods,goods+n,cmp);
for(int i=0;i<n;i++)
{
t=Find(goods[i].d);
if(t>0)
{
sum+=goods[i].p;
f[t]=t-1;
}
}
printf("%d\n",sum);
}
return 0;
}