首页 > 代码库 > poj1456(贪心+并查集)

poj1456(贪心+并查集)

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

 

题意: 有n个商品, 已知每个商品的价格和销售截止日期, 每销售一件商品需要花费一天, 即一天只能销售一件商品, 问最多能买多少钱;

 

思路: 贪心..需要买最多的钱, 而且每件商品销售花费的时间都一样多, 那么我们尽量把值钱的商品买完就好啦...对数据按价格排序, 把贵的先买, 并且尽量推迟其销售日期, 因为它不能超过截止日期销售嘛, 尽量推迟其销售日期就能减少其与截止日期小于它并且比较有价值的商品冲突啦...

 

代码:

 1 #include <iostream>
 2 #include <stdio.h>
 3 #include <algorithm>
 4 #include <math.h>
 5 #include <string.h>
 6 #define MAXN 10010
 7 using namespace std;
 8 
 9 int main(void){
10     int n, vis[MAXN];
11     pair<int, int> p[MAXN];
12     while(scanf("%d", &n)!=EOF){
13         int x, y, gg=0;
14         memset(vis, 0, sizeof(vis));
15         for(int i=0; i<n; i++){
16             scanf("%d%d", &p[i].first, &p[i].second);
17         }
18         sort(p, p+n);
19         int ans=0;
20         for(int i=n-1; i>=0; i--){
21             for(int j=p[i].second; j>0; j--){
22                 if(!vis[j]){  //***第j天没有被占用
23                     vis[j]=1;
24                     ans+=p[i].first;
25                     break;
26                 }
27             }
28         }
29         printf("%d\n", ans);
30     }
31     return 0;
32 }

 

上面的时间复杂度 为n*k, 如果数据比价坑的话可能超时(这题的数据还是比较水的啦)...我们可以优化一下..怎么优化呢...可以用并查集啦;

 

 1 #include <iostream>
 2 #include <stdio.h>
 3 #include <algorithm>
 4 #include <math.h>
 5 #include <string.h>
 6 #define MAXN 10010
 7 using namespace std;
 8 
 9 int pre[MAXN];
10 
11 int find(int x){
12     return x==pre[x]?x:pre[x]=find(pre[x]);
13 }
14 
15 int main(void){
16     int n;
17     pair<int, int> p[MAXN];
18     while(scanf("%d", &n)!=EOF){
19         int x, y, gg=0;
20         for(int i=0; i<=MAXN; i++){
21             pre[i]=i;
22         }
23         for(int i=0; i<n; i++){
24             scanf("%d%d", &p[i].first, &p[i].second);
25         }
26         sort(p, p+n);
27         int ans=0;
28         for(int i=n-1; i>=0; i--){
29             int gg=find(p[i].second); //***gg为商品i截止日期前最大的没有被占用的日期,即商品i最晚可以的出售日期
30             if(gg>0){
31                 ans+=p[i].first;
32                 pre[gg]=gg-1; //***gg被商品i占用了, 将gg指向前一个位置
33             }
34         }
35         printf("%d\n", ans);
36     }
37     return 0;
38 }

 

poj1456(贪心+并查集)