时间:2016-03-18 09:05:15 星期五
题目编号:[2016-03-18][POJ][1456][Supermarket]
题目大意:给定一个物品清单,求最大能卖出的商品价值
分析:
- 贪心,显然价值大的先卖,然后价值大的应该从最后一天开始卖,即如果最后一天能卖就最后一天,否则就往前一天(前面有物品已经占用那天了)
- 求maxprofit 的时候,可以用dp递推,对于没见物品,更新一次期限内的信息
- 也可以用并查集优化,fa[i] 更新维护第i天及其往前没有卖过物品的日期,这里用了压缩路径,第二次查找就会快些,如果没有压缩路径,那么和直接从日期开始往前逐天查找没有区别
方法:贪心排序+并查集优化
#define _WORK_#ifdef _WORK_#include <algorithm>#include <cstdio>using namespace std;typedef long long LL;#define FOR(x,y,z) for(int (x)=(y);(x)<(z);++(x))const int maxp = 10000 + 100;const int maxn = 10000 + 100;int fa[maxp];void ini(int n){ FOR(i,0,n + 1) fa[i] = i;}int fnd(int x){ return x == fa[x]?x:fa[x] = fnd(fa[x]);}void uni(int x,int y){ x = fnd(x);y = fnd(y); if(x == y )return ; fa[x] = y;}struct Product{ int val,dead; bool operator < (const Product & a){ return a.val < val || (a.val == val && a.dead < dead); }}a[maxn];int main(){ //freopen("in.txt","r",stdin); //freopen("out.txt","w",stdout); int n; while(~scanf("%d",&n)){ int maxtime = 0; FOR(i,0,n){ scanf("%d%d",&a[i].val,&a[i].dead); if(a[i].dead > maxtime) maxtime = a[i].dead; } ini(maxtime); sort(a,a+n); int ans = 0; FOR(i,0,n){ int t = fnd(a[i].dead); if(t){ fa[t] = t-1; ans += a[i].val; } } printf("%d\n",ans); } return 0;}#endif