POJ 1456 Supermarket

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


题意一堆物品有利润和到期的时间, 求出最大的利润。


方法一:贪心+双向队列 

找到最大时间Maxtime  按照时间由大到小排序  因为一步操作需要消耗一个单位时间,就将time从Maxtime一步一步往前推,只要当前物品的时间 大于等于 time 就加入队列,队列按照利润最大的在前面 ,time每次减少1  ans就加上队列最前的利润。。。。


#include<iostream>
#include<cstdio>
#include<queue>
#include<algorithm>
using namespace std;
#define N 10100

struct Node
{
    int p, q;
    friend bool operator < (const Node &a, const Node &b){
        return a.q > b.q;
    }
}arr[N];

priority_queue<int> q;

int main ()
{
    int n;
    while(scanf("%d", &n) != EOF)
    {
        int MAX = 0;
        for(int i = 1; i <= n; i++)
          {
            scanf("%d %d", &arr[i].p, &arr[i].q);
            if(arr[i].q > MAX) MAX = arr[i].q;
          }

        sort(arr+1, arr+n+1);
        while(!q.empty()) q.pop();

        int ans = 0, cur = 1;
        for(int t = MAX; t >= 1; t--)
        {
            while(cur <= n && arr[cur].q >= t)
                q.push(arr[cur++].p);

            if(!q.empty()){
                ans += q.top();
                q.pop();
            }
        }
        printf("%d\n", ans);
    }
    return 0;
}



方法二:贪心+并查集 这个贪心的思想和上面不同,这次把物品按照利润由大到小排序,然后开始从1开始占领截止日期,如果该时期被占,那么就往前面推,知道推到日期为0.   并查集的用处就是用来标记,这样就可以直接找出 截止日期为n的物品可以最晚在那一天卖掉


#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
#define N 11000
int F[N];
struct Node
{
	int p, q;
}ha[N];

int cmp(Node a, Node b)
{
	if (a.p == b.p) return a.q < b.q;
	return a.p > b.p;
}


int fun(int x)
{
	if (F[x] != x)
		F[x] = fun(F[x]);
	return F[x];
}
int main()
{
	int n;
	while (scanf("%d", &n) != EOF)
	{
		int Max = 0;
		for (int i = 1; i <= n; i++)
		{
			scanf("%d %d", &ha[i].p, &ha[i].q);
			Max = max(Max, ha[i].q);
		}

		for (int i = 0; i <= Max; i++)
			F[i] = i;

		sort(ha + 1, ha + 1 + n, cmp);

		int ans = 0;
		for (int i = 1; i <= n; i++)
		{
			int d = fun(ha[i].q);
			if (d > 0){
				ans += ha[i].p;
				F[d] = d - 1;
			}
		}
		printf("%d\n", ans);
	}
	return 0;
}








  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值