解题思路:这个题目的思路是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; }
- Source Code(贪心+堆优化)