思路:
-
贪心(可加并查集优化)
-
贪心:
- 选取方法:先将物品按价值从高到低排序,尽量把出售物品的时间向后放,不要影响前面的物品。
拿最高价物品A来说:- 有没有可能不选择这个最高价值的物品呢?如果不选它,那必定是在它的截止日期可以售出更高价的物品,但是它已经是最高价的啦,所以一定要卖它。
- 有没有可能在之前卖它可以获利更大呢?如果可以,必然是有某个物品B本来不能卖,现在能卖了,可是A和B仍然在B的deadline前占了两个位置,完全可以在A的deadline卖出A。
- 优先队列和sort基本无区别。
- 选取方法:先将物品按价值从高到低排序,尽量把出售物品的时间向后放,不要影响前面的物品。
-
并查集优化:
- 优化查找,取消 vis,par[i] 代表 i 之前的最末空闲。
- 每卖出一个物品,如在第 i 天卖,则 par[i] 要改成 i - 1。
- par[i] 如果是 0 ,说明这个物品没法卖。
代码:
- 优先队列贪心:141ms 988kB
//141ms 988kB
#include <iostream>
#include <cstring>
#include <cstdio>
#include <queue>
using namespace std;
const int maxn = 10005;
int N;
int ans;
bool vis[maxn];
struct NODE{
int p;
int d;
friend bool operator < (NODE a , NODE b)
{
if(a.p == b.p)
return a.d < b.d;
return a.p < b.p;
}
NODE(int _p,int _d) : p(_p) , d(_d) {} ;
};
priority_queue <NODE , vector<NODE> , less<NODE> > Q;
void INIT(){
ans = 0;
memset(vis , 0 , sizeof(vis));
return ;
}
int main(){
while(cin>>N){
INIT();
while(N--){
int a,b;
scanf("%d%d" , &a , &b);
Q.push(NODE(a,b));
}
while(Q.size()){
NODE cur = Q.top() ; Q.pop() ;
int d = cur.d;
while(d){
if(!vis[d]){
vis[d] = true;
ans += cur.p ;
break;
}
d--;
}
}
cout<<ans<<endl;
}
return 0;
}
- sort贪心:141ms 820kB
//141ms 820kB
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
using namespace std;
const int maxn = 10005;
int N;
int ans;
bool vis[maxn];
struct NODE{
int p;
int d;
friend bool operator < (NODE a , NODE b)
{
if(a.p == b.p)
return a.d > b.d;
return a.p > b.p;
}
};
NODE node[maxn];
void INIT(){
ans = 0;
memset(vis , 0 , sizeof(vis));
return ;
}
int main(){
while(cin>>N){
INIT();
for(int i=0;i<N;i++){
int a,b;
scanf("%d%d" , &node[i].p , &node[i].d);
}
sort(node , node+N);
for(int i=0;i<N;i++){
int d = node[i].d ;
while(d){
if(!vis[d]){
vis[d] = true;
ans += node[i].p;
break;
}
d--;
}
}
cout<<ans<<endl;
}
return 0;
}
- 并查集优化:63ms 1020kB
//63ms 1020kB
#include <iostream>
#include <cstring>
#include <cstdio>
#include <queue>
using namespace std;
const int maxn = 10005;
int N;
int ans;
struct NODE{
int p;
int d;
friend bool operator < (NODE a , NODE b)
{
if(a.p == b.p)
return a.d < b.d ;
return a.p < b.p ;
}
NODE(int p , int d) : p(p) , d(d) {} ;
};
priority_queue <NODE , vector<NODE> , less<NODE> > Q;
int par[maxn];
void INIT(){
ans = 0;
memset(par , -1, sizeof(par));
return ;
}
int FIND(int i){
return par[i] == -1 ? i : par[i] = FIND(par[i]);
}
int main(){
while(cin>>N){
INIT();
int a, b;
for(int i=1;i<=N;i++){
scanf("%d%d" , &a , &b);
Q.push(NODE(a,b));
}
while(Q.size()){
NODE cur = Q.top() ; Q.pop() ;
int d = cur.d;
int pard = FIND(d);
if(!pard)
;
else{
par[pard] = pard - 1;
ans += cur.p;
}
}
cout<<ans<<endl;
}
return 0;
}