• POJ1456 Supermarket 并查集


    欢迎访问~原文出处——博客园-zhouzhendong

    去博客园看该题解


    题目传送门 - POJ1456


    题意概括

       一家超市,要卖出N种物品(每种物品各一个),每种物品都有一个卖出截止日期Di(在该日期之前卖出可以获得收益,否则就无法卖出),且每种物品被卖出都有一个收益值Pi. 卖出每个物品需要耗时1天,且任一时刻只能卖出一个物品。给出这N种物品的Di和Pi,求最大收益值。


    题解

      堆的做法大概是第一感,闭着眼睛应该都可以想到。

      堆的做法:倒着来,对于每一天,如果有产品在当天结束销售,那么把他们扔进堆里面。每天选择最贵的销售。

      但是正着来怎么搞??

      我们用并查集维护。

      先给所有的产品按照价格从大到小排序。

      然后对于每一个产品尽量靠后销售。

      比如当前产品确定在第x天销售,那么我们就把答案加上去,fa[x]=getf(x-1)。

      如果x=0,那么自然不销售,也不做任何操作。


    代码

    #include <cstring>
    #include <algorithm>
    #include <cstdio>
    #include <cstdlib> 
    #include <cmath>
    using namespace std;
    const int N=10005;
    int n,fa[N];
    struct Pro{
    	int p,d;
    }p[N];
    bool cmp(Pro a,Pro b){
    	if (a.p==b.p)
    		return a.d>b.d;
    	return a.p>b.p;
    }
    int getf(int k){
    	return fa[k]==k?k:fa[k]=getf(fa[k]);
    }
    int main(){
    	while (~scanf("%d",&n)){
    		for (int i=1;i<=n;i++)
    			scanf("%d%d",&p[i].p,&p[i].d);
    		sort(p+1,p+n+1,cmp);
    		for (int i=0;i<=10000;i++)
    			fa[i]=i;
    		int ans=0;
    		for (int i=1;i<=n;i++){
    			int day=getf(p[i].d);
    			if (!day)
    				continue;
    			ans+=p[i].p;
    			fa[day]=getf(day-1);
    		}
    		printf("%d
    ",ans);
    	}
    	return 0;
    }
    

      

  • 相关阅读:
    1.2 软件测试的分类和职业生涯
    1.1:软件测试的发展
    1,select查询详解
    7、网页
    6、开学典礼
    5、边框属性和display
    4、盒子模型和margin、padding
    3、字体、背景、和文本的属性
    2、Css中的样式选择器
    16. C# 对象初始化器
  • 原文地址:https://www.cnblogs.com/zhouzhendong/p/POJ1456.html
Copyright © 2020-2023  润新知