侧边栏

POJ-1456 Supermarket

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

题意:n个商品,有价值和保质期,每个商品只能在保质期内卖出,问最大收益

思路:贪心,按照价值降序排序,再把每个商品按顺序安排进保质期日,如果该日被安排了,就安排进保质期前面最近的日子。用并查集更新这个日子,每次都把这一天的根节点连到他的前一天的根节点上,这样在查找的时候该点的根节点就是离他最近的日子

代码:

 1 //#include<bits/stdc++.h>
 2 #include<iostream>
 3 #include<vector>
 4 #include<stack>
 5 #include<string>
 6 #include<cstdio>
 7 #include<algorithm>
 8 #include<queue>
 9 #include<map>
10 #include<set>
11 #include<cmath>
12 #include<iomanip>
13 #define inf 0x7f7f7f7f
14 #define mem(a) memset(a,0,sizeof(a))
15 //#define scanf scanf_s
16 using namespace std;
17 typedef long long ll;
18 const int M = int(1e5) + 5;
19 int root[M];
20 void init(int n) {
21     for (int i = 0; i <= n; i++) {
22         root[i] = i;
23     }
24 }
25 int find(int x) {
26     return root[x] == x ? x : root[x] = find(root[x]);
27 }
28 void merge(int x) {
29     x = find(x);
30     int y = find(x-1);
31     root[x] = y;
32 }
33 struct node {
34     int p, d;
35 };
36 node a[M];
37 bool cmp(node a, node b) {
38     return a.p > b.p;
39 }
40 signed main()
41 {
42     int n;
43     while (cin>>n) {
44         init(M);
45         mem(a);
46         for (int i = 0; i < n; i++) {
47             cin >> a[i].p >> a[i].d;
48         }
49         sort(a, a + n, cmp);
50         int ans = 0;
51         for (int i = 0; i < n; i++) {
52             int pd = find(a[i].d);
53             if (pd != 0) {
54                 ans += a[i].p;
55                 merge(pd);
56             }
57         }
58         cout << ans << endl;
59     }
60     return 0;
61 }

备注:一开始疯狂wa,结果是初始化的锅,我再也不给init写参数惹QAQ

posted @ 2019-05-19 23:04  晴人  阅读(146)  评论(0编辑  收藏  举报