sort算法排序 std_算法交流: 超市销售【算法之贪心】

题目描述】 超市销售 By Oler42wa
超市里有N件商品,每个商品都有利润pi和过期时间di,每天只能卖一件商品,过期商品(即当天di<=0)不能再卖。求合理安排每天卖的商品的情况下,可以得到的最大收益是多少。
输入包含多组测试用例,测试用例最多30组。每组测试用例,以输入整数N开始,接下来输入N对pi和di,分别代表第i件商品的利润和过期时间。在输入中,数据之间可以自由穿插任意个空格或空行,输入至文件结尾时终止输入,保证数据正确。对于每组产品,输出一个该组的最大收益值。每个结果占一行。【样例输入】4 50 2 10 1 20 2 30 1
7 3 1 2 1 10 3 100 2 8 2 1 20 50 10 【样例输出】80
169一、题意分析典型的贪心算法例题,要求最大收益值,则在保证商品不过期的前提下,将利润越大的商品先出售。二、算法说明把产品按最后期限从大到小排,然后从最大的那个期限时间往前一天一天推,如果当前天的期限产品没有完全卖出,就放到前一天期限,和前一天最后期限的产品一走卖,利润大的就先卖。没有卖出的又放到前一天去卖,这样从大期限往小期限推,因为小期限的产品不可能在大期限时间去卖,而大期限的产品可以在小的期限去卖。
语句sort(ans,ans+n,**)是调用排序函数对n个商品进行如上排序,在计算最大收益值的函数中通过循环调用排序函数,按最大过期时间前推,每天卖掉一个利润最大商品。三、数据结构用结构体类型定义数组。四、算法分析1. 对商品过期时间和利润的排序是通过调用函数实现,避免了在主函数中排序出现的繁多代码。

5d7df210329fa3139d25a79554a5f4ff.png

2. 用函数实现最大收益值计算,每天卖掉的最大利润的商品也是通过排序函数找出的,使得下一个卖掉的商品始终排在第一位,整体上减少了代码量,同时函数的使用也使得整个代码易懂。五、代码与调试#include<bits/stdc++.h>
#include<iostream>
#include<algorithm>
using namespace std;
#define N 10005//定义范围
typedef struct
{
int p,d;//利润与过期时间
}node;
node ans[N];
int paixv(node a,node b)//最后期限从大到小排
{
return a.d>b.d;
}
int pai(node a,node b)//利润从大到小排序
{
return a.p>b.p;
}
int answer(int n)
{
if(n==0)
return 0;
int flag,max,a,money=0;
for(int i=ans[0].d;i>0;i--) //从最大期限开始卖
{
if(ans[0].d!=i)//跳过无商品出售的天
continue;
flag=0;
while(ans[flag].d==ans[flag+1].d)//过期时间相同的商品数
flag++;
sort(ans,ans+flag+1,pai);//该过期时间内商品利润从大到小排序
money=money+ans[0].p;
ans[0].d=ans[0].p=0;//已卖商品归零
for(int j=1;j<flag+1;j++)//其余商品都放到前一天去卖
ans[j].d--;
sort(ans,ans+n,paixv);//剩余商品重排列
n--;
}
return money;
}
int main()
{
int n,l,i;
while(scanf("%d",&n)>0)//商品数
{
for( i=0;i<n;i++)
scanf("%d%d",&ans[i].p,&ans[i].d);//输入价值和保质期
sort(ans,ans+n,paixv);
printf("%ldn",answer(n));
}
return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值