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

题目大意:

有N件商品,分别给出商品的价值和销售的最后期限,只要在最后日期之前销售处,就能得到相应的利润,并且销售该商品需要1天时间。

问销售的最大利润。

 

我开始的代码:(贪心策略有问题,因为我当时以为过期时间短的商品要优先卖掉,实际上不是这样的)

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
#define MAXN 10000+100 struct node
{
int val;
int day;
}; bool mysort(node a, node b) //按照天数从小到大排序,若天数相同,就按价格从大到小排序
{
if (a.day != b.day)return a.day < b.day;
return a.val > b.val;
} int main()
{
int n;
while (scanf("%d", &n) != EOF)
{
int i, j; int sum = ;
node dday[MAXN];
dday[].day = ; dday[].val = ;
for (int i = ; i <=n; i++)
{
scanf("%d%d", &dday[i].val, &dday[i].day);
}
sort(dday+, dday + n+,mysort); //注意这里我是从i=1,开始存数据的,所排序的时候也要从i=1开始排序
int ans = ;
for (i = ; i <= n; i++)
{
if (dday[i].day != dday[i - ].day)
{
ans += dday[i].day - dday[i - ].day-; //dday[i-1]到dday[i]之间空闲的天数,可以存起来,留给后面时间冲突的天数使用
sum += dday[i].val;
}
else
{
if (ans>)
{
ans--; //若之前有空余的天数,那么可以拿一天留到现在来销售
sum += dday[i].val;
}
}
}
printf("%d\n", sum);
}
return ;
}

虽然能过样例,但是还有一些情况没有想到。比如,不一定要过期时间越早的商品越先销售,因为,如果后面有价值更大的商品由于时间的冲突不能卖出的话,完全可以舍弃之前销售价值最小的商品,来卖这件价值更大的商品。

比如数据 :

5 1 3 15 2 5 3 20 2 10 1

正确答案为 40 而我的代码答案为35

然后换另一种贪心思想:

将商品的价值从大到小排序,找到销售的最大期限,用visit数组标记,如果它的期限没有被占用,就在该天销售,如果占用,则从它的前一天开始向前查找有没有空闲的日期,如果有则占用。这样就可以得到最大销售量。


#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define N 10010
bool visit[N]; struct node
{
int profit, deadline;
}p[N]; bool operator <(node a, node b)
{
return a.profit > b.profit;
} int main()
{
int num;
int maxprofit;
while (~scanf("%d", &num))
{
maxprofit = 0;
memset(visit, false, sizeof(visit));
for (int i = 1; i <= num; ++i)
{
scanf("%d %d", &p[i].profit, &p[i].deadline);
}
sort(p + 1, p + num + 1); //注意这里是从p+1开始排序
for (int i = 1; i <= num; ++i) //优先价值最大
{
if (!visit[p[i].deadline])
{
maxprofit += p[i].profit;
visit[p[i].deadline] = true;
}
else
{
for (int j = p[i].deadline - 1; j >= 1; --j)
{
if (!visit[j])
{
maxprofit += p[i].profit;
visit[j] = true;
break;
}
}
}
}
printf("%d\n", maxprofit);
}
return 0;
}

并查集做法,原理与上面差不多

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define N 10010
int pre[N]; struct node
{
int profit, deadline;
}p[N]; bool operator < (const node& a, const node& b)
{
return a.profit > b.profit;
} int find(int x) //寻找该点的根节点
{
int root, temp;
root = x;
while (root != pre[root])
root = pre[root];
while (x != root) //压缩路径
{
temp = pre[x];
pre[temp] = root;
x = temp;
}
return root;
} int main()
{
int num;
int root;
int maxprofit;
while (~scanf("%d", &num))
{
maxprofit = ;
for (int i = ; i < N; ++i) //注意这里i小于的是N,不是num
pre[i] = i;
for (int i = ; i < num; ++i)
scanf("%d%d", &p[i].profit, &p[i].deadline);
sort(p, p + num);
for (int i = ; i < num; ++i)
{
root = find(p[i].deadline);
if (root > )
{
pre[root] = root - ;
maxprofit += p[i].profit;
}
}
printf("%d\n", maxprofit);
}
return ;
}

2018-04-21 

POJ-1456 Supermarket 销售商品【贪心】+【并查集】的更多相关文章

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

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

  2. POJ 1456 Supermarket 区间问题并查集||贪心

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

  3. poj 1456 Supermarket - 并查集 - 贪心

    题目传送门 传送点I 传送点II 题目大意 有$n$个商品可以销售.每个商品销售会获得一个利润,但也有一个时间限制.每个商品需要1天的时间销售,一天也只能销售一件商品.问最大获利. 考虑将出售每个物品 ...

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

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

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

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

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

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

  7. POJ - 1456 贪心+并查集

    做法一:直接贪心,按照利润排序,然后直接尽量给每个活动安排到最晚的时间即可.时间复杂度O(n * d)当d都为10000时,很容易超时.由于这题数据比较水,所有贪心未超时. AC代码 #include ...

  8. poj 1456 Supermarket(并查集维护区间)

     题意:有一些货物,每一个货物有价值和卖出的截至日期,每天能够卖一个货物,问能卖出的最大价值是多少. 思路:算法不难想到,按价值降序排列.对于每一件货物,从deadline那天開始考虑.假设哪天空 ...

  9. poj1456 Supermarket 贪心+并查集

    题目链接:http://poj.org/problem?id=1456 题意:有n个物品(0 <= n <= 10000) ,每个物品有一个价格pi和一个保质期di (1 <= pi ...

随机推荐

  1. POJ1113 Wall【凸包】

    题意: 求把城堡围起来需要的最小墙壁周长. 思路: 围墙周长为=n条平行于凸包的线段+n条圆弧的长度=凸包周长+围墙离城堡距离L为半径的圆周长. 代码: ...还是看大佬写的,自己做个记录方便日后复习 ...

  2. mongodb系列~mongodb的副本集(1)

    一 简介: mongodb副本集 二 复制方式: 1 全量复制 2 增量复制三 同步检测过程:    一 正常情况下:       1 master执行语句,并将所有的修改数据库的操作以日志Oplog ...

  3. bootstrap3在IE8下导航不显示,自动识别成手机模式

    想让bootstrap3兼容ie8,需要将html5shiv.js.respond.js还有bootstrap的所有css.js文件都放在本地服务器空间,不能用CDN. bootstrap所有css. ...

  4. 关于django1.7.7使用ajax后出现“CSRF token missing or incorrect”问题的解决办法

    最近使用Python3.3.25和django1.7.7开发公司项目,在使用ajax来post数据时,居然一直提示:403错误,原因是“CSRF token missing or incorrect” ...

  5. [转]SPI通信原理简介

    [转自]http://www.cnblogs.com/deng-tao/p/6004280.html 1.前言 SPI是串行外设接口(Serial Peripheral Interface)的缩写.是 ...

  6. Linux内核驱动之GPIO子系统(一)GPIO的使用【转】

    转自:http://blog.csdn.net/tommy_wxie/article/details/9427047 一 概述 Linux内核中gpio是最简单,最常用的资源(和 interrupt  ...

  7. javascript 添加行,删除行,datepicker获取当前日期和上一个月日期并设置格式,笔记

    $(function () { getdatepicker(); today(); getPreMonth(); getdatetimepicker(); }); function today(){ ...

  8. QML C++插件dll引用

    插件的创建非常简单,但是它可以复用,并且为不同的应用程序扩展类型.使用创建的插件是非常灵活的解决方案.关于插件一个很好的例子见QmlBook-In-Chinese 中最后一章介绍的例子. 本文主要备忘 ...

  9. Ex 3_17 无穷路径..._十一次作业

    (a) Inf(p)在p中出现了无穷多次,说明Inf(p)存在一个环当中,所以这个环的顶点肯定是某一个强连通部件的子集. (b) 若G中存在一条无穷路径,则G中至少存在一个环,且这个环至少有两个顶点, ...

  10. ubuntu系统下Python虚拟环境的安装和使用

    ubuntu系统下Python虚拟环境的安装和使用        前言:进行python项目开发的时候,由于不同的项目需要使用不同的资源包和相关的配置,因此创建多个python虚拟环境,在虚拟环境下开 ...