标签:buying iss rom lap temp min rip success display
题目传送门:http://acm.hdu.edu.cn/showproblem.php?pid=6438
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 1233 Accepted Submission(s): 407
有 N 个商店,小商按顺序走过每个商店(不能回头),在每个商店它可以选择在那个商店以那个商店的价格买入或者卖出一件物品,当然他也可以选择不买不卖。小商的背包容量无限大。我需要做的是使得小商走过所有商店之后获得最大的利润以及他所花费的交易次数。
之前牛客暑假多校的一个变形,不只是能拿一个了,可以拿很多个。这道题的解法也是贪心,但是与之前那道很不一样。
首先他可以买多个商品,也就是说,他可能有反悔的机会,也就是说虽然他前面已经把那件商品卖掉了,但如果后面有比前面更优的选择,他其实可以反悔,之前不卖不出去而是等到更优的时候再卖。
而我们要做的就是为他提供一个可以反悔的机会。
这时候就需要用 STL 里的优先队列来维护一个最小堆了,而最小堆里面的是买入的商品(这里指的买入的商品其实更确切的说是加上交换得来的商品,但交换而来的商品要区别于直接花钱买的商品,所以要打上标记),堆顶的值是这些商品中价格最小的。
有了这个反悔神器,小商每到一家商店就可以把商店的交易价和堆顶的值做比较,如果比堆顶的值大的则买入(拿便宜的换贵的嘛),盈利值就是贵的和便宜的价钱之差,并把当前这家商店的商品丢进堆里,那么原本堆顶用于交换的那件呢怎么办呢?这就要看它是当时花钱买来的还是换来的了,如果是花钱买来的就直接不要啦并且操作数+1;如果是交换而来的,那么就去掉标记重新入堆(这种情况下我们发现其实它相当于一个中转物品了,这件贵的物品其实是跟交换它的那件物品进行交换了,而不是跟它,所以操作数不变并且要去掉标记)。如果当前商店的交易价比堆顶的要小呢,当然丢进堆里啦(反正现在丢进堆里又不用钱),如果后面有机会用高价换掉它的话又赚一波。所以有了这个时光机,商人可是稳赚不赔的啊。
AC code:
1 #include <bits/stdc++.h> 2 #define INF 0x3f3f3f3f 3 #define ll long long int 4 using namespace std; 5 const int MAXN = 1e5+10; 6 int N; 7 struct tp{ 8 int x, v; 9 bool sell; 10 bool friend operator<(tp a, tp b) 11 { 12 if(a.v == b.v) return !a.sell; 13 return a.v > b.v; 14 } 15 }; 16 int main() 17 { 18 int T_case, a; 19 scanf("%d", &T_case); 20 while(T_case--) 21 { 22 priority_queue<tp> Q; 23 scanf("%d", &N); 24 scanf("%d", &a); 25 tp temp; 26 temp.x = 1; 27 temp.v = a; 28 temp.sell = false; 29 Q.push(temp); 30 ll ans = 0, time = 0; 31 for(int i = 2; i <= N; i++) 32 { 33 scanf("%d", &a); 34 temp.sell = false; 35 if(a > Q.top().v) 36 { 37 tp top = Q.top(); 38 Q.pop(); 39 ans+=a-top.v; 40 if(top.sell) 41 { 42 top.sell = false; 43 Q.push(top); 44 } 45 else time++; 46 temp.sell = true; 47 } 48 temp.x = i; 49 temp.v = a; 50 Q.push(temp); 51 } 52 printf("%lld %lld\n", ans, time*2); 53 } 54 return 0; 55 }
2018中国大学生程序设计竞赛 - 网络选拔赛 1001 - Buy and Resell 【优先队列维护最小堆+贪心】
标签:buying iss rom lap temp min rip success display
原文地址:https://www.cnblogs.com/ymzjj/p/9538286.html