有n件商品,每件商品有它的利润和售出的最后期限,问能够得到的最大利润是多少
这道题和 HDU 1789 Doing Homework again 几乎一模一样,只不过这个是求最的扣分,本题是求最大利润
朴素的做法是:
按照每件商品的利润从大到小排序,有一个busy数组记录那天是否有东西卖出。对于每件商品,从它的截止日期开始遍历,如果那天有东西卖就看看前一天是否有卖东西,直到有一天没有东西卖或者前面的天数都有卖的。
1 //#define LOCAL 2 #include <iostream> 3 #include <cstdio> 4 #include <cstring> 5 #include <algorithm> 6 using namespace std; 7 8 const int maxn = 10000 + 10; 9 struct Product 10 { 11 int p, d; 12 bool operator< (const Product& a) const 13 { 14 return p > a.p || (p == a.p && d > a.d); 15 } 16 }products[maxn]; 17 bool busy[maxn]; 18 19 int main(void) 20 { 21 #ifdef LOCAL 22 freopen("1456in.txt", "r", stdin); 23 #endif 24 25 int n; 26 while(scanf("%d", &n) == 1) 27 { 28 memset(busy, false, sizeof(busy)); 29 for(int i = 0; i < n; ++i) 30 scanf("%d%d", &products[i].p, &products[i].d); 31 sort(products, products + n); 32 33 int ans = 0; 34 for(int i = 0; i < n; ++i) 35 { 36 for(int j = products[i].d; j > 0; --j) 37 { 38 if(!busy[j]) 39 { 40 ans += products[i].p; 41 busy[j] = true; 42 break; 43 } 44 } 45 } 46 printf("%d ", ans); 47 } 48 return 0; 49 }
并查集优化:
这里parent数组相当于之前代码的busy数组的优化。因为对于第i件商品我们都要从它的期限往前遍历来找到不忙的那天来卖,parent[i]存放第i天最近的能卖物品的天数。
1 //#define LOCAL 2 #include <iostream> 3 #include <cstdio> 4 #include <cstring> 5 #include <algorithm> 6 using namespace std; 7 8 const int maxn = 10000 + 10; 9 struct Product 10 { 11 int p, d; 12 bool operator< (const Product& a) const 13 { 14 return p > a.p || (p == a.p && d > a.d); 15 } 16 }products[maxn]; 17 int parent[maxn]; 18 19 int Find(int a) 20 { 21 return parent[a] == a ? a : parent[a] = Find(parent[a]); 22 } 23 24 int main(void) 25 { 26 #ifdef LOCAL 27 freopen("1456in.txt", "r", stdin); 28 #endif 29 30 int n, maxday; 31 while(scanf("%d", &n) == 1) 32 { 33 maxday = 0; 34 for(int i = 0; i < n; ++i) 35 { 36 scanf("%d%d", &products[i].p, &products[i].d); 37 if(products[i].d > maxday) maxday = products[i].d; 38 } 39 40 sort(products, products + n); 41 42 int ans = 0; 43 for(int i = 0; i <= maxday; ++i) 44 parent[i] = i; 45 for(int i = 0; i < n; ++i) 46 { 47 int pi = Find(products[i].d); 48 if(pi > 0) 49 { 50 parent[pi] = Find(pi - 1); 51 ans += products[i].p; 52 } 53 } 54 printf("%d ", ans); 55 } 56 return 0; 57 }