题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6438
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 |
题目大意:一个常见的物品买卖问题,(话说最近碰见的物品买卖好多啊,要不要总结一个专题??)
一个人,开局无限多的金钱,只能往前走,不能后退,他碰到的商品可以选择买或者买,最后要求能够获得的收益最大,同时买卖的次数最少;
牛客网2018多校练习赛有一个这样的题,也是商品买卖,可以看一看;手中只能拿一个的物品买卖
还有CF的一道题(这个是我看别人的链接,就顺便写了写,就当专项训练了):一次只能交易一次的物品买卖
思路都差不多:每输入一个数,先买入,然后判断前面有没有比他小的数,有的话,前面的那个卖出,这个再次买入,相当于前面的那个变成了这个,然后标记一下为中间变量,如果后面的能用到,就相当于没有它,如果后面的用不到,则相当于它就是最后的结果,不用管;
因为我们是用的加减法算最大收益之和,因此1,2,10和1,10的收益是相同的,只考虑买卖次数即可;
对于次数,碰见中间变量减去1即可;
ac:
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<map>
//#include<set>
#include<deque>
#include<queue>
#include<stack>
#include<bitset>
#include<string>
#include<fstream>
#include<iostream>
#include<algorithm>
using namespace std;
#define ll long long
#define INF 0x3f3f3f3f
//#define mod 1e9+7
//#define max(a,b) (a)>(b)?(a):(b)
//#define min(a,b) (a)<(b)?(a):(b)
#define clean(a,b) memset(a,b,sizeof(a))// 水印
//std::ios::sync_with_stdio(false);
int n;
struct cmp{
bool operator ()(const ll &a,const ll &b){
return a>b;
}
};
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
priority_queue<ll,vector<ll>,cmp> que;
map<ll,int> vis;//ll价格做中间商品的数量int
vis.clear();
while(que.size())
que.pop();
ll ans=0,cnt=0;
scanf("%d",&n);
for(int i=1;i<=n;++i)
{
ll x;
scanf("%lld",&x);
que.push(x);
if(que.top()<x)//可以交易
{
cnt++;//交易
ans=ans+x-que.top();//收入
if(vis[que.top()])//这个商品是中间商品
{
cnt--;
vis[que.top()]--;
}
que.pop();//卖出
que.push(x);//还可以再买,
//相当于最小价值的商品变成了x,
//可以选择不卖,这样相当于没有买入x
vis[x]++;//该商品做了中间商
//(这种价格做的中间商++)
}
}
printf("%lld %d\n",ans,cnt*2);
}
}