标签:int money 查集 find products poj1456 include day 贪心
题目链接: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\n", 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\n", ans) ; delete p; } }
标签:int,money,查集,find,products,poj1456,include,day,贪心 来源: https://www.cnblogs.com/dlutjwh/p/10709429.html
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。