首页 > 其他 > 详细

poj_1456 贪心

时间:2015-09-15 00:12:02      阅读:320      评论:0      收藏:0      [点我收藏+]

题目大意

    一家超市,要卖出N种物品(每种物品各一个),每种物品都有一个卖出截止日期Di(在该日期之前卖出可以获得收益,否则就无法卖出),且每种物品被卖出都有一个收益值Pi. 卖出每个物品需要耗时1天,且任一时刻只能卖出一个物品。给出这N种物品的Di和Pi,求最大收益值。

题目分析

    求最优值问题,可以考虑动态规划、贪心、搜索+剪枝等算法。尝试用贪心法来分析。 
    考虑在日期D以及D之后卖出物品可以获得的最大收益,因为这样就可以只考虑售出截止日期Di>=D的那些物品了,类似于无后效性。日期D从max{Di}(i>=1 && i <= N}到1递减,对于每个D,都存在可以被卖出的物品的集合S(满足物品的售出截止日期大于等于D即可),从这些物品中选取出来收益最大的那个物品A,进行售出,同时将A从S中消除;D每次减1的时候,可能导致有更多的物品可以被售出,则将这些物品加入集合S,同时从S中选出最大收益的那个进行售出,并剔除集合..... 
    由于需要选择集合S中收益最大的那个物品,因此使用优先队列进行维护。

实现(c++)

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<queue>
#include<vector>
using namespace std;
#define MAX_PRODUCT_NUM 10005
struct Product{
	int profit;
	int deadline;
};
Product gProducts[MAX_PRODUCT_NUM];
struct Cmp2{
	bool operator()(int a, int b){
	return a < b;
	}
};

bool Cmp1(const Product& p1, const Product& p2){
	return p1.deadline > p2.deadline;
}
int main(){
	int n;
	while (scanf("%d", &n) != EOF){
		for (int i = 0; i < n; i++){
			scanf("%d %d", &gProducts[i].profit, &gProducts[i].deadline);
		}
		sort(gProducts, gProducts + n, Cmp1);
		int last_deadline = gProducts[0].deadline;
		int sum = 0;
		int k = 0;
		priority_queue<int, vector<int>, Cmp2> Q;
		while (k < n && last_deadline >= 1){
			while (k < n && gProducts[k].deadline >= last_deadline){
				Q.push(gProducts[k].profit);
				k ++;
			}
			if (!Q.empty()){
				sum += Q.top();
				Q.pop();
			}
			last_deadline--;
		}
		while (last_deadline){
			if (!Q.empty()){
				sum += Q.top();
				Q.pop();
			}
			last_deadline--;
		}
		printf("%d\n", sum);
	}
	return 0;
}

 

poj_1456 贪心

原文:http://www.cnblogs.com/gtarcoder/p/4808892.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!