zoukankan      html  css  js  c++  java
  • poj1456 Supermarket 贪心+并查集

    题目链接:http://poj.org/problem?id=1456

    题意:有n个物品(0 <= n <= 10000) ,每个物品有一个价格pi和一个保质期di (1 <= pi <= 10000, 1 <= di <= 10000),物品必须在保质期之前卖出。且每天只能卖出一个物品,问如何安排才能使卖出的总价格最大。

    这道题贪心的思想很明显,先将物品的价格按照从大到小排序,再按照该顺序卖物品,如果存在不超过保质期的最大可用日期,则该物品能够卖出,并将这一天标记。关键在于如何找这个日期,就是在一个有序序列中查找小于等于当前日期的最大值,再将其删除,继续查找。这个可以用set来做。

    #include <iostream>
    #include <algorithm>
    #include <stdio.h>
    #include <stack>
    #include <set>
    #include <istream>
    #include<queue>
    #include<stack>
    #include <cstring>
    #include <string>
    //#include <climits>
    using namespace std;
    struct products {
    	int money, day;
    };
    bool cmp(products a, products b) {
    	if (a.money != b.money)
    		return a.money > b.money;
    	return a.day>b.day;
    }
    int main() {
    	int n;
    	while (scanf("%d", &n) != EOF) {
    		set<int> s;
    		products *p = new products[n];
    		int md = 0;
    		for (int i = 0;i < n;i++) {
    			scanf("%d%d", &p[i].money, &p[i].day);
    			md = max(p[i].day, md);
    		}
    		for (int i = 1;i <= md;i++)
    			s.insert(i);
    		sort(p, p + n, cmp);
    		int ans = 0;
    		for (int i = 0;i < n && !s.empty();i++) {
    			if (*s.begin() > p[i].day)
    				continue;
    			set<int>::iterator iter = s.upper_bound(p[i].day);
    			iter--;
    			//cout << *iter << -1 << endl;
    			if (*iter <= p[i].day) {
    				ans += p[i].money;
    				s.erase(iter);
    			}
    		}
    		printf("%d
    ", ans);
    		delete[]p;
    	}
    }
    

      

    除了这种解法外,我们还可以用并查集来维护,初始化每个日期i的父亲为自己,当当前的日期i被占用后,将其父亲设为前一天的日期i-1,每次查找i的最大可用日期即查找i的祖先即可,由于使用路径压缩,所以查找的复杂度很低,比用set块

    #include <iostream>
    #include <algorithm>
    #include <cstdio>
    using namespace std;
    class union_find_set {
    public:
    	union_find_set(int n) {
    		fa = new int[n];
    		rank = new int[n];
    		for (int i = 0; i < n; i++)
    			fa[i] = i;
    	}
    	~union_find_set()
    	{
    		delete fa,rank;
    	};
    	int find(int x) {
    		if (fa[x] == x)
    			return x;
    		return fa[x] = find(fa[x]);
    	}
    	void unite(int x, int y) {
    		x = find(x);
    		y = find(y);
    		if (x == y)
    			return;
    		if (rank[x] < rank[y])
    			fa[x] = y;
    		else {
    			fa[y] = x;
    			if (rank[x] == rank[y])
    				rank[x]++;
    		}
    	}
    	bool same(int x, int y) {
    		if (find(x) == find(y))
    			return 1;
    		return 0;
    	}
    	int n;
    	int *fa,*rank;
    };
    
    
    struct products {
    	int money, day;
    };
    
    bool cmp(products a, products b) {
    	return a.money > b.money;
    }
    int main() {
    	int n;
    	while (scanf("%d", &n) != EOF) {
    		products *p = new products[n];
    		int md = 0;
    		for (int i = 0;i < n;i++) {
    			scanf("%d%d", &p[i].money,&p[i].day);
    			md = max(p[i].day, md);
    		}
    		union_find_set P(md + 1);
    		sort(p, p + n, cmp);
    		int ans = 0;
    		for (int i = 0;i < n;i++) {
    			int t = P.find(p[i].day);
    			if (t > 0) {
    				ans += p[i].money;
    				P.fa[t] = t - 1;
    			}
    		}
    		printf("%d
    ", ans) ;
    		delete p;
    	}
    }
    

      

  • 相关阅读:
    Building a Space Station POJ
    Networking POJ
    POJ 1251 Jungle Roads
    CodeForces
    CodeForces
    kuangbin专题 专题一 简单搜索 POJ 1426 Find The Multiple
    The Preliminary Contest for ICPC Asia Shenyang 2019 F. Honk's pool
    The Preliminary Contest for ICPC Asia Shenyang 2019 H. Texas hold'em Poker
    The Preliminary Contest for ICPC Asia Xuzhou 2019 E. XKC's basketball team
    robotparser (File Formats) – Python 中文开发手册
  • 原文地址:https://www.cnblogs.com/dlutjwh/p/10709429.html
Copyright © 2011-2022 走看看