• POJ 1456 Supermarket(贪心+并查集)


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

    题目大意:有n件商品,每件商品都有它的价值和截止售卖日期(超过这个日期就不能再卖了)。卖一件商品消耗一个单位时间,售卖顺序是可以改变的,求出最多可以卖多少钱。

    解题思路:看了大牛的解释~。其实这道题是用贪心写的,这里并查集只是用来作为工具,使得速度更加快。贪心的写法是这样的,先把所有产品按照利润从大到小排序,然后这个把这个放在截止日期那天卖出,并做好标记,如果截至日期那天已经有其他产品占用了,那么可以把这个产品卖出的时间往前推,直到找到可以卖的那一天并标记好。其实直接写也可以,但是可以用并查集优化。 对于快速找到第一个不冲突的时间点呢,使用并查集很好地解决了这个问题。 这里并查集的作用类似于链表指针,压缩的过程就是删掉节点的过程。从而在O(1)的时间内找到那个不冲突的点。

    代码1:普通贪心(127ms)

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<algorithm>
     4 using namespace std;
     5 const int N=1e4+5;
     6 
     7 int vis[N];
     8 
     9 struct node{
    10     int dx,val;
    11     bool operator <(const node &b)const{
    12         return val>b.val;
    13     }
    14 }arr[N];
    15 
    16 int main(){
    17     int n,ans;
    18     while(~scanf("%d",&n)){
    19         ans=0;
    20         memset(vis,0,sizeof(vis));
    21         for(int i=1;i<=n;i++){
    22             scanf("%d%d",&arr[i].val,&arr[i].dx);
    23         }
    24         sort(arr+1,arr+1+n);
    25         for(int i=1;i<=n;i++){
    26             for(int j=arr[i].dx;j>=1;j--){
    27                 if(!vis[j]){
    28                     ans+=arr[i].val;
    29                     vis[j]=1;
    30                     break;
    31                 }
    32             }
    33         }
    34         printf("%d
    ",ans);
    35     }
    36     return 0;
    37 }

    代码2:贪心+并查集(47ms)

     1 #include<cstdio>
     2 #include<cmath>
     3 #include<cctype>
     4 #include<cstring>
     5 #include<iostream>
     6 #include<algorithm>
     7 #include<vector>
     8 #include<queue>
     9 #include<set>
    10 #include<map>
    11 #include<stack>
    12 #include<string>
    13 #define LC(a) (a<<1)
    14 #define RC(a) (a<<1|1)
    15 #define MID(a,b) ((a+b)>>1)
    16 using namespace std;
    17 typedef long long LL;
    18 const int INF=0x3f3f3f3f;
    19 const int N=1e4+5;
    20 
    21 int root[N];
    22 
    23 int find(int x){
    24     return x==root[x]?x:root[x]=find(root[x]);
    25 }
    26 
    27 struct node{
    28     int dx,val;
    29     bool operator <(const node &b)const{
    30         return val>b.val;
    31     }
    32 }arr[N];
    33 
    34 int main(){
    35     int n,ans;
    36     while(~scanf("%d",&n)){
    37         ans=0;
    38         for(int i=1;i<N;i++){
    39             root[i]=i;
    40         }
    41         for(int i=1;i<=n;i++){
    42             scanf("%d%d",&arr[i].val,&arr[i].dx);
    43         }
    44         sort(arr+1,arr+1+n);
    45         for(int i=1;i<=n;i++){
    46             int t=find(arr[i].dx);
    47             if(t>0){
    48                 ans+=arr[i].val;
    49                 root[t]=t-1;
    50             }
    51         }
    52         printf("%d
    ",ans);
    53     }
    54     return 0;
    55 }
  • 相关阅读:
    scala学习笔记(8)
    mysql复习(1)基本CRUD操作
    sql获得表主键信息
    C#缓存-依赖 CacheHelper
    MVC过滤器实现用户登录验证
    MVC过滤器
    MVC页面和表单
    在ASP.NET中基于Owin OAuth使用Client Credentials Grant授权发放Token
    MVC DbContext
    MVC数据注解
  • 原文地址:https://www.cnblogs.com/fu3638/p/7658389.html
Copyright © 2020-2023  润新知