题目链接: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;
}
}

  

poj1456 Supermarket 贪心+并查集的更多相关文章

  1. POJ 1456 Supermarket(贪心+并查集优化)

    一开始思路弄错了,刚开始想的时候误把所有截止时间为2的不一定一定要在2的时候买,而是可以在1的时候买. 举个例子: 50 2  10 1   20 2   10 1    50+20 50 2  40 ...

  2. POJ_1456 Supermarket 【并查集/贪心】

    一.题面 POJ1456 二.分析 1.贪心策略:先保证从利润最大的开始判断,然后开一个标记时间是否能访问的数组,时间尽量从最大的时间开始选择,这样能够保证后面时间小的还能够卖. 2.并查集:并查集直 ...

  3. POJ 1456 Supermarket(贪心+并查集)

    题目链接:http://poj.org/problem?id=1456 题目大意:有n件商品,每件商品都有它的价值和截止售卖日期(超过这个日期就不能再卖了).卖一件商品消耗一个单位时间,售卖顺序是可以 ...

  4. POJ1456:Supermarket(并查集+贪心)

    Supermarket Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 17634   Accepted: 7920 题目链接 ...

  5. POJ 1456——Supermarket——————【贪心+并查集优化】

    Supermarket Time Limit:2000MS     Memory Limit:65536KB     64bit IO Format:%I64d & %I64u Submit  ...

  6. poj1456(贪心+并查集)

    题目链接: http://poj.org/problem?id=1456 题意: 有n个商品, 已知每个商品的价格和销售截止日期, 每销售一件商品需要花费一天, 即一天只能销售一件商品, 问最多能买多 ...

  7. Supermarket(贪心/并查集)

    题目链接 原创的博客 题意: 超市里有N个商品. 第i个商品必须在保质期(第di天)之前卖掉, 若卖掉可让超市获得pi的利润. 每天只能卖一个商品. 现在你要让超市获得最大的利润. n , p[i], ...

  8. POJ 1456 (贪心+并查集) Supermarket

    有n件商品,每件商品有它的利润和售出的最后期限,问能够得到的最大利润是多少 这道题和 HDU 1789 Doing Homework again 几乎一模一样,只不过这个是求最的扣分,本题是求最大利润 ...

  9. POJ1456 Supermarket —— 贪心 + 路径压缩优化

    题目链接:http://poj.org/problem?id=1456 Supermarket Time Limit: 2000MS   Memory Limit: 65536K Total Subm ...

随机推荐

  1. postgresql数据库中~和like和ilike的区别

     ~(暂且叫他波浪号吧) 和 LIKE 和 ILIKE 操作符可以模糊匹配字符串,LIKE是一般用法,ILIKE匹配时则不区分字符串的大小写,~ 波浪号则可以使用正则匹配. LIKE和 ILIKE 它 ...

  2. Go语言中的闭包

    一.函数的变量作用域和可见性 1.全局变量在main函数执行之前初始化,全局可见 2.局部变量在函数内部或者if.for等语句块有效,使用之后外部不可见 3.全局变量和局部变量同名的情况下,局部变量生 ...

  3. iptables 限制ip访问3306端口

    *filter:INPUT DROP [0:0]  #全部关闭:FORWARD ACCEPT [0:0]:OUTPUT ACCEPT [0:0]-A INPUT -s 172.4.4.14 -p tc ...

  4. vue路由参数变化刷新数据

    当路由到某个组件时,由于组件会复用,所以生命周期函数不会再次执行, 如果这个组件是模板组件,靠传入不同数据来显示的.那么,可能会发生参数变化了但页面数据却不变化. 问题 假如有个组件 info.vue ...

  5. App自动化(1)--Appium-Android环境搭建

    本次笔记记录Appium-Android环境搭建,主要实现在windows上通过python编写脚本来实现模拟器上安装的app自动化测试. 主要步骤:安装node.js,配置JDK环境,配置Andro ...

  6. Shell脚本统计文件行数

    Shell脚本统计文件行数 转自 http://www.jb51.net/article/61943.htm    示例:row_count.sh文件 awk '{print NR}' row_cou ...

  7. HTML 重定向 页面跳转

    通过响应头重定向 响应状态 301 和 302 可以指定重定向URL, 推荐使用302 FOUND HttpServletResponse. static final int SC_MOVED_TEM ...

  8. pandas 使用panel 报错 Panel is deprecated and will be removed in a future version.

    Panel is deprecated and will be removed in a future version.The recommended way to represent these t ...

  9. NIPS2017-The neural hawks process

    NIPS2017哪些论文值得关注 论文链接 1.首先这篇文章研究的是 event stream,什么是event stream呢 ? 假如你是一个医生,你每天会看到很多病人 ,对于每一个病人,你都有他 ...

  10. 转化.vdi到.vmdk

    OracleVirtualBox转化.vdi到.vmdk E:\Genymotion-deployed\CentOS_7_64>"D:/Program Files/Oracle/Vir ...