POJ1456

本文介绍了一种使用贪心算法结合并查集或堆优化的任务调度问题解决方案。通过将产品按利润排序并在其截止日期前尽可能早地安排出售,实现最大化的收益。文中提供了两种实现方式的源代码示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

解题思路:这个题目的思路是1:贪心+堆优化;2:贪心+并查集优化。我这里用的是并查集优化。首先是把产品按照它的利润由大到小排好序,然后依次将产品在离他的deadline最近的一天内卖出。在这里用并查集,是把连续占用的天数看成一个集合,而他们的根节点就是离他们最近的左边的未占用的一天。这样要找到产品的销售日,就找到它的根节点就好了。如果根节点为-1,就说明这个产品无法卖出。否则,就把i和find(i-1)合并起来。
  • Source Code(用贪心+并查集)
    #include<iostream>
    #include<stdio.h>
    #include<stdlib.h>
    #include<algorithm>
    using namespace std;
    const int MAXSIZE = 10005;
    struct Product{
    	int p;
    	int d;
    };
    Product pro[MAXSIZE];
    bool cmp(const Product& p1,const Product& p2){
    	return p1.p>p2.p;
    }
    int father[MAXSIZE];
    void init(int n){
    	for(int i =0;i<n;i++){
    		father[i] = i;
    	}
    }
    int find(int x){
    	if(father[x] == -1) return -1;
    	if(father[x]!=x){
    		father[x] = find(father[x]);
    	}
    	return father[x];
    }
    bool isValid(Product &e){
    	int a = find(e.d-1);
    	if(a<0) return false;
    	if(a==0) father[0]=-1;
    	else{
    		father[a] = find(father[a-1]);
    	}
    	return true;
    }
    int main(){
    	int n;
    	while(scanf("%d",&n)==1){
    		int max =0;
    		int value = 0;
    		for(int i =1;i<=n;i++){
    			scanf("%d%d",&pro[i].p,&pro[i].d);
    			if(pro[i].d>max) max = pro[i].d;
    		}
    		init(max);
    		sort(pro+1,pro+n+1,cmp);
    		for(int i=1;i<=n;i++){
    			if(isValid(pro[i])){
    				value+=pro[i].p;
    			}
    		}
    		cout<<value<<endl;
    	}
    	return 0;
    }
    
    
    
    
    • Source Code(贪心+堆优化)
      #include<iostream>
      #include<stdio.h>
      #include<stdlib.h>
      #include<algorithm>
      #include<queue>
      #include<vector>
      using namespace std;
      const int MAXSIZE = 10005;
      struct Product{
      	int p;
      	int d;
      };
      Product pro[MAXSIZE];
      bool cmp(const Product& p1,const Product& p2){
      	return p1.d<p2.d;
      }
      bool operator < (const Product& p1,const Product& p2){
      	return p2.p<p1.p;
      }
      priority_queue<Product> pQueue;
      int main(){
      	int n;
      	while(scanf("%d",&n)==1){
      		int max =0;
      		int value = 0;
      		int i;
      		for(i =1;i<=n;i++){
      			scanf("%d%d",&pro[i].p,&pro[i].d);
      		}
      		sort(pro+1,pro+n+1,cmp);
      		while(!pQueue.empty()) pQueue.pop();
      		for(i=1;i<=n;i++){
      				if(pro[i].d>pQueue.size()) pQueue.push(pro[i]);
      				else if(pro[i].p>pQueue.top().p){
      					pQueue.pop();
      					pQueue.push(pro[i]);
      				}
      			}
      			while(!pQueue.empty()){
      				value+=pQueue.top().p;
      				pQueue.pop();
      			}
      		cout<<value<<endl;
      	}
      	return 0;
      }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值