链接: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