2018 Buy and Resell (贪心)

题目:
https://acm.hdu.edu.cn/showproblem.php?pid=6438

假如ai<a(i+1),而且a(i+1)<a(i+2)

如果我们在i买入,在i+1卖出,在i+1买入,在i+2卖出,得到的收益是-pi+p(i+1)-p(i+1)+p(i+1)

如果我们在i买入,在i+2卖出,得到的收益是-pi+p(i+1)

i+1作为中间商对我们的收益是没有影响的,只需要在统计次数的时候将中间商删去就行(中间商交易了不止一次,只要在mp不是第一次出现的,都是中间商)

相当于强制买入

 关于加入两次的理解是

(3条消息) CodeForces 867E Buy Low Sell High(优先队列,贪心)_riba2534的博客-CSDN博客

这位大佬说的

1.做中间价

2.做所有买入价中的一个

 

 

 

例如5

1 2 3 4 5

按照这个就是

1 -1    1买入,1卖出

2 -1    1买入,2卖出

3 -2    2买入,3卖出  (2相当于中间商,实际上是1->3)

4 -2    2买入,4卖出

5 -3    3买入,5卖出  (3相当于中间商,实际上是1->5)

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>

#include <string>
#include <stack>
#include <queue>
#include <vector>
#include <set>
#include <map>
#define endl "\n"
#define ls (rt<<1)
#define rs (rt<<|1)
#define mid ((l+r)<<1)
using namespace std;
typedef long long ll;
inline ll gcd(ll a, ll b) { ll r; while (b > 0) { r = a % b; a = b; b = r; }return a; }
typedef pair<ll, ll> P;
const int maxn = 1e5+7;
priority_queue<int ,vector<int> ,greater<int> > que;
map<int,int> mp;
int main()
{
    int t;
    scanf("%d",&t);
    int n;
    while(t--)
    { int n;
      while(!que.empty())
        que.pop();
       mp.clear();
    scanf("%d",&n);
    ll ans=0;
    ll cnt=0;
       for(int i=1;i<=n;i++)
       {
           int x;
           scanf("%d",&x);
           if(!que.empty()&&que.top()<x)
           {  cnt++;
             //中间商
               int nw=que.top();
                 que.pop();
                ans+=x-nw;
               que.push(x);
               que.push(x);
                if(mp[nw])
                {
                    cnt--;
                    mp[nw]--;
                }
                mp[x]++;
           }
           else
                 que.push(x);
       }
       printf("%lld %lld\n",ans,cnt*2);

    }
}

一样的思路的

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>

#include <string>
#include <stack>
#include <queue>
#include <vector>
#include <set>
#include <map>
#define endl "\n"
#define ls (rt<<1)
#define rs (rt<<|1)
#define mid ((l+r)<<1)
using namespace std;
typedef long long ll;
inline ll gcd(ll a, ll b) { ll r; while (b > 0) { r = a % b; a = b; b = r; }return a; }
typedef pair<ll, ll> P;
const int maxn = 1e5+7;
priority_queue<int ,vector<int> ,greater<int> > que;
priority_queue<int > q;

map<int,int> mp;
int main()
{
    int t;
    scanf("%d",&t);
    int n;
    while(t--)
    { int n;
      while(!q.empty())
        q.pop();
       mp.clear();
    scanf("%d",&n);
    ll ans=0;
    ll cnt=0;
       for(int i=1;i<=n;i++)
       {
           int x;
           scanf("%d",&x);
           q.push(-x);
           q.push(-x);
           mp[x]++;
           cnt++;
           int nw=q.top();
           q.pop();
          if(mp[-nw])
          {
              mp[-nw]--;
              cnt--;
          }
           ans+=x+nw;
       }

       printf("%lld %lld\n",ans,cnt*2);

    }
}

 

posted @ 2021-08-25 15:33  废柴废柴少女  阅读(39)  评论(0)    收藏  举报