poj1456(贪心加并查集)

题意:给出一些物品的利润和卖出的截至日期(即过了这个日期此物品就不能再卖出),每一天最多只能卖一件物品。问能获得的最大利润是多少。

解题思路:大体就是贪心吧。其中用到了类似于并查集的工具;
先按照物品的利润从大到小排序,然后从利润大的开始将其卖出时间定为截至日期之前最近的那个未被利用的一天(当然包括截止日期本天)。在寻找之前最近未被利用的一天时用到了parent这个数组,有点像并查集,及时维护能使复杂度大大降低。关于这个算法的正确性,我是这样理解的。尽量使得利润大的卖出去,找之前最近的一天是因为尽量不阻碍后继其他物品的卖出,如果仍然阻碍了其他物品卖出的话,顶多阻碍其他一个物品,而被阻碍的物品的利润一定是相等或更小的,所以这样贪心的话得到的一定是最多的利润。

代码:
#include <iostream>
#include <algorithm>
#include <stdio.h>
#include <cstring>

using namespace std;
struct point
{
    int weight;
    int day;
};
bool operator<(point a,point b)
{
    returna.weight>b.weight;
}
point points[10001];
int parent[10001];
int getparent(int k)
{
   if(k<0)
    return k;
    if(parent[k]==k)
    return k;
    returnparent[k]=getparent(parent[k]);
}
bool vis[10001];
int n;
int main()
{
   while(scanf("%d",&n)==1)
    {
       for(int i=0;i<=10000;i++)
       parent[i]=i;
       memset(vis,0,sizeof vis);
       for(int i=0;i<n;i++)
       {
          scanf("%d%d",&points[i].weight,&points[i].day);
       }
       sort(points,points+n);
       long long ans=0;
       for(int i=0;i<n;i++)
       {
           inttool=getparent(points[i].day);
          if(tool>0)
           {
          vis[tool]=true;
          parent[tool]=getparent(tool-1);
          ans+=points[i].weight;
           }
       }
      cout<<ans<<'\n';
    }
    return 0;
}




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值