POJ1456

解题思路:这个题目的思路是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、付费专栏及课程。

余额充值