错题-商店

商店

题目大意

题目描述

一条街上有 n 个商店,在第 i 个商店,可以以 a i a_i ai 的价格买入一个商品,也可以以 a i a_i ai 的价格卖出一个商品。商品很沉,最多只能同时拿着 1 个商品在街上走。现在按照给定顺序依次访问所有商店,那么,最大收益是多少?在获得最大收益的前提下,最少交易次数是多少?

输入格式

第一行一个整数 T (1≤T≤5),代表测试用例个数
下面 T 组数据,其中每一组数据都占两行,其中
第一行一个整数 n (1≤n≤105),代表商店个数
下面一行 n 个整数,其中第 i 个数为 * a i a_i ai​ (0≤ a i a_i ai*​<2147483648),代表在第 i 个商店可以买入或卖出商品的价格

输出格式

对于每个例子,输出一行两个整数,分别代表最大收益和获得最大收益的前提下最少的交易次数

测试样例

输入:

1
5
9 10 7 6 8 

输出:

3 4
解法

​ 首先使用贪心算法,一家一家商铺看,如果后一家商铺的 a i a_i ai 大于当前这家,则就将商品在当前这家买入并在后一家卖出,否则就不在当前这家商铺购买商品。通过该策略可确定最大收益。

​ 设置变量 maichu 用来记录上一次卖出商品的商铺,当下一次购买时就判断买入的商铺下标是否和上一次相同,若相同,就不再增加交易次数,否则交易次数增加 2 (因为买入一次,卖出一次)。

时间复杂度

O ( T n ) O(Tn) O(Tn)

​ 最外层输入测试用例的时间复杂度为 O ( T ) O(T) O(T) ;输入各个商铺的 a i a_i ai 的时间复杂度为 O ( n ) O(n) O(n) ;判断是否进行交易的循环中时间复杂度为 O ( n ) O(n) O(n) 。综上,时间复杂度为 O ( T n ) O(Tn) O(Tn)

代码
#include <bits/stdc++.h>
using namespace std;
long long a[1000000] = {0}; //记录商品价格
// 0 1 1 2 3
int main()
//一天天看,如果后一项小于前一项就不买,也不可能存在后一项小于前一项的时候买前一项会赚,因为直接买后一项赚更多
{
     int T;
     scanf("%d", &T);
     for (int i = 1; i <= T; i++)
     {
          long long n;
          scanf("%lld", &n);
          for (long long j = 0; j < n; j++)
          {
               scanf("%lld", &a[j]);
          }

          long long W = 0;       //记录收益
          long long time1 = 0;   //记录交易次数
          long long maichu = -1; //记录上一次卖出商品的商铺
          for (long long j = 0; j < n - 1; j++)
          {
               if (a[j] < a[j + 1]) //若满足后一天价格比今天高,就买入
               {
                    W += (a[j + 1] - a[j]);
                    if (j != maichu) //计算最少交易次数,当当前交易买入与前一天的卖出相同就可以省略
                    {
                         time1 += 2;
                    }
                    maichu = j + 1;
               }
               else if (a[j] == a[j + 1]) //假交易,当价格相同的时候又遇到前一天买进,则也要假装买进然后明天卖出,因为为了保证最少交易次数,要是遇到价格相同好几天又最后升价了,就要一直假交易买进卖出直到后一天价格比前一天低(即亏本)或是到了最后一天
               {                          //即我昨天买进又遇到今明两天价格相同,那么今天就要假交易
                    if (j == maichu)
                    {
                         maichu = j + 1;
                    }
               }
          }

          cout << W << ' ' << time1 << endl;
     }
     return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值