zoj-2921 Stock ***

 1 /*纯粹转, http://hi.baidu.com/sheep_finalfreedom/blog/item/1fbb2046408dd889b3b7dc4a.html */

2 /*
3 http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=2921
4
5 最初以为是DP,后来想通之后发现是非常经典的贪心!
6
7 采用的策略就是倒过来,从最后一天开始卖!
8
9 虽然最后一天的股票可能还包含了前面几天没卖掉了股票,
10 但是当天的价格对于每张股票都是一样的,
11 所以我们用贪心策略,
12 先把最后一天自身的股票能卖多少卖多少,
13 卖完之后如果还能再卖得话,
14 就把这个配额加到倒数第二天去,
15 这样倒数第二天的股票就有两种选择,
16 卖倒数第二天的价格或者卖最后一天的价格,
17 当然是选价格最高的卖,
18 如果卖完还有配额就加到倒数第三天,
19 以此类推
20
21 在加配额的时候用优先队列,每次pop都抛出价格最高的配额即可!
22 *
23 */
24 #include <iostream>
25 #include <queue>
26 using namespace std;
27
28 struct share
29 {
30 int price,size;
31 friend bool operator< (share n1, share n2)
32 {
33 return n1.price< n2.price;
34 }
35 };
36 priority_queue <share> q;
37
38 int g[100001];
39 int p[100001];
40 int s[100001];
41
42 int main()
43 {
44 //freopen("debug\\in.txt","r",stdin);
45 int repeat,m,i;
46 int total,temp;
47 share tt;
48 cin>>repeat;
49 while(repeat--)
50 {
51 cin>>m;
52 for(i=1;i<=m;i++)
53 scanf("%d%d%d",&g[i],&p[i],&s[i]);
54
55 while(!q.empty())
56 q.pop();
57 total=0;
58 for(i=m;i>=1;i--)
59 {
60 tt.price=p[i];
61 tt.size=s[i];
62 q.push(tt);
63 temp=g[i];
64 while(!q.empty()&&temp)
65 {
66 tt=q.top();
67 q.pop();
68 if(temp>=tt.size)
69 {
70 temp-=tt.size;
71 total+=tt.size*tt.price;
72 }
73 else
74 {
75 total+=temp*tt.price;
76 tt.size=tt.size-temp;
77 q.push(tt);
78 temp=0;
79
80
81 }
82 }
83
84 }
85 cout<<total<<endl;
86 }
87
88 return 0;
89 }

你可能感兴趣的:(ZOJ)