http://acm.hdu.edu.cn/showproblem.php?pid=6438
Buy and ResellTime Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 759 Accepted Submission(s): 199 Problem Description The Power Cube is used as a stash of Exotic Power. There are n cities numbered 1,2,…,n where allowed to trade it. The trading price of the Power Cube in the i -th city is ai dollars per cube. Noswal is a foxy businessman and wants to quietly make a fortune by buying and reselling Power Cubes. To avoid being discovered by the police, Noswal will go to the i -th city and choose exactly one of the following three options on the i -th day:
Input There are multiple test cases. The first line of input contains a positive integer T (T≤250 ), indicating the number of test cases. For each test case:
Output For each case, print one line with two integers —— the maximum profit and the minimum times of trading to get the maximum profit.
Sample Input 3 4 1 2 10 9 5 9 5 9 10 5 2 2 1
Sample Output 16 4 5 2 0 0 Hint In the first case, he will buy in 1, 2 and resell in 3, 4. profit = - 1 - 2 + 10 + 9 = 16 In the second case, he will buy in 2 and resell in 4. profit = - 5 + 10 = 5 In the third case, he will do nothing and earn nothing. profit = 0 |
题意:你有无数的钱,每次只能买卖一件物品,在获得最大利润的同时,要使得交易次数最少。输出最大利润和交易次数。
分析:贪心,贪心大法好,自己贪心能力比较弱了
/*#include<bits/stdc++.h>
using namespace std;
typedef long long ll;*/
#include<bits/stdc++.h>
#define ll long long
#define inf 0x3f3f3f3f
using namespace std;
int n,m;
ll ans,tmp,x,num;
///https://blog.csdn.net/qq_37891604/article/details/81321394
///不懂优先队列的可以看上面这篇博客
priority_queue<ll,vector<ll>,greater<ll> >q,p;///队头元素最小,即队列里的元素有小到大排,例如1 2 3
///为什么由小到大,因为肯要尽量买便宜的吗
///p:已经卖了的钱(以这个钱卖的)
///q:将要卖的钱(将要以这个价格卖出)(买进来放到队列里,将要把它卖掉)
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
scanf("%d",&n);
ans=num=0;
while(!p.empty())p.pop();
while(!q.empty())q.pop();
for(int i=0;i<n;i++)
{
scanf("%lld",&x);
if(!p.empty())///已经卖
{
tmp=p.top();///已经卖的
if(tmp<x&&!q.empty()&&q.top()<tmp)
{///q.top()<tmp将要卖的小于已经卖的,tmp<x已经卖得小于当前的价格,
///q.top<tmp是因为tmp<q.pop<x的时候就要卖tmp
num++;
ans+=x;///将要卖的以x价格卖出
q.pop();
p.push(x);
}
else if(tmp<x)
{///tmp<x已经卖得小于当前的价格,也就是卖便宜了,那我反悔,我要在现在把它卖了
p.pop();
q.push(tmp);
ans-=2*tmp;///以前卖它赚了tmp,需要减去,然后再买回它来,比如tmp=5,x=10,以前以5元卖出赚了5,首先把我赚的五元减去,在花5元买它
ans+=x;
p.push(x);
}
else if(!q.empty()&&q.top()<x)///将要卖的价格小于现在的价格
{
num++;
p.push(x);
ans+=x;
q.pop();
}
else
{
ans-=x;///先假买了,放到将要卖的队列里
q.push(x);
}
}
else if(!q.empty()&&q.top()<x)///将要卖
{
num++;
p.push(x);
ans+=x;
q.pop();
}
else
{
ans-=x;///先假买了,放到将要卖的队列里
q.push(x);
}
}
while(!q.empty())///把假买的多减掉的钱加回来
{
ans+=q.top();
q.pop();
}
printf("%lld %lld\n",ans,num*2);
}
return 0;
}