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 }

 

转载于:https://www.cnblogs.com/geloutingyu/p/6121408.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值