poj 1456 supermarket(贪心+并查集优化)

问题:SupermarketPOJ - 1456

给出n个商品的价格和过期天数,问如果一天只能卖一件,问最大可能营业额

分析:

贪心策略1:

从最后一天开始往前走,每走一天,就把这一天要过期的商品纳入选择列表,每一天都把当前列表里面最贵的商品卖出,直到第一天

贪心策略2:

把所有的商品按价格从大到小排序,从最大的开始选,将其所对应的最后一天选中,如果选到当前的最大价格商品时,其所对应的最后一天已经有价格更高的商品卖出了,则再之前的日子里面选一天卖出,如果找不到这样的一天,就去尝试下一个商品,这个商品也就买不了了。这样的策略保证了每一天都卖出可以卖出的最大价值,因为假若在某一种方法里,该天卖出了一个价格更高的商品,则在我们的策略里面,这样的一个商品在之前已经考虑过了,要么截止日期在该天之前,那所谓的某种更优方法就不存在,要么就被放在了该天之后的某一天,那么我们的策略不可能比某种方案更差;

策略2里面采用并查集优化,一天如果已经有商品卖出,就和前一天合并(以前一天为根),每一次看商品可不可以卖的时候,就直接看它所在区间最后一天的根是谁就可以了,如果根已经到了头,就不能卖了

代码1(策略1):

#include
#include
#include
#include
using namespace std;
priority_queue que; 
struct prod{
	int value,day;
	bool operator < (const prod& a){
		return day>a.day;
	}
}prods[10100];
int main(){
	int n;
	while(cin>>n){
		while(!que.empty())que.pop();
		for(int i=1;i<=n;i++){
			cin>>prods[i].value>>prods[i].day;
		}
		sort(prods+1,prods+1+n);
		int sum=0,now=prods[1].day;
		que.push(prods[1].value);
		int i=2;
		while(now>=1&&i>=1){
			while(i>=1&&prods[i].day==now){
				que.push(prods[i].value);
				i++;
			}
			if(!que.empty()){
				sum+=que.top();//cout<

代码2(策略2):

#include
#include
using namespace std;
struct product{
	int money,day;
	bool operator < (const product& c){
		return money>c.money;
	}
}pros[10020];
int fa[10020],ceng[10020];
void init(int n){
	for(int i=1;i<=n;i++){
		fa[i]=i;ceng[i]=0;
	}
}
int find(int i){
	return fa[i]==i?i:fa[i]=find(fa[i]);
}
void unite(int i){
	int fi=find(i),ff=find(i-1);
	if(fi==ff)return;
	fa[fi]=ff;
}
int main(){
	int n;
	while(cin>>n){
		init(10010);
		int num=0;
		for(int i=1;i<=n;i++){
			//cout<<"hi"<>pros[i].money>>pros[i].day;
		}
		sort(pros+1,pros+1+n);
		for(int i=1;i<=n;i++){
			int d=pros[i].day,p=pros[i].money;
			if(find(d)!=0){
				//cout<<"before fa20="<

你可能感兴趣的:(ACM_贪心算法,ACM_数据结构)