# POJ1456_Supermarket

题意:


n 个商品,第 i 个商品利润 p[i] ,会在 d[i] 天过期(可以在第 [1, d[i]] 天之间售出,不能在第 d[i]+1 天售出)

问可以获得的最大利润

解:


【并查集+贪心】:

【贪心】:

①:显然,优先考虑利润较大的商品如何售出

②:为了尽可能的包容其他商品,一个商品应该在过期之前尽可能晚地卖出

【并查集】:

首先将所有商品关于利润从大到小排序

从1到n依次考虑每个商品

根据上文分析,第 i 个商品最好能在 di 天卖出,但是如果发现第 di 天已经在之前“安排”上了要卖别的商品,

就依次考虑在第 di1, di2, ... 2, 1 天售出,如果找不到空位则不售出第 i 个商品

但是,暴力从 di 天开始往前枚举显然是不可取的

考虑这样一种解决方案

以每一天为元素做并查集,初始化 fa[x]=xx 代表第 x

假设第1个商品在 d1 天过期,查询 fa[d1]=d1 ,就把第1个商品放在第 d1 天卖出,同时合并第 d1 天和第 d11 天的集合

即令 fa[d1]=d11

假设第2个商品也恰在第 d1 天过期,查询 fa[d1]=d11 ,就把第2个商品放在第 d11 天售出,同时令 fa[d11]=d12

若对于第 x 天的查询 fa[x]=0 证明第 [1, x] 天中没有空位,此商品不再售出

以此类推,此过程类似于链表查询,顺次向前查找第一个空位,但由于并查集具有路径压缩算法,查询时间可降至常数级别

代码:


int n; struct PRODUCT{ int p, d; }a[10010]; int sale[10010], fa[10010]; int ans; int find(int x) { if (fa[x] == x) return x; return fa[x] = find(fa[x]); } bool cmp(PRODUCT x, PRODUCT y) { return x.p > y.p; } int main() { while (cin >> n) { memset(sale, 0, sizeof sale); int maxd = 0; for (int i = 1; i <= n; i++) cin >> a[i].p >> a[i].d, maxd = max(maxd, a[i].d); for (int i = 1; i <= maxd; i++) fa[i] = i; sort(a + 1, a + 1 + n, cmp); for (int i = 1; i <= n; i++) { int rt = find(a[i].d); if (rt == 0) continue; sale[rt] = a[i].p; fa[rt] = rt - 1; } ans = 0; for (int i = 1; i <= maxd; i++) ans = ans + sale[i]; cout << ans << endl; } return 0; }

__EOF__

本文作者熹圜
本文链接https://www.cnblogs.com/Xiwon/p/13379687.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   熹圜  阅读(102)  评论(0编辑  收藏  举报
编辑推荐:
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
点击右上角即可分享
微信分享提示