• 牛客网 暑期ACM多校训练营(第二场)D.money-贪心 or 动态规划


    D.money

    贪心,直接贴官方的题解吧。

    题目大意

    你要按照顺序依次经过n个商店,每到达一个商店你可以购买一件商品,也可以出售你手中的商品。 同一时刻你手上最多拿一件商品。在第i个商店购买和出售的代价都是a[i]。 问你经过完n个商店后的最大收益。 同时,在最大化收益的前提下,求最小的交易次数。 

    做法

     DP

    f[i][0/1]表示已经访问完了i个商店,你手中是否有商品,此时的最大收益。 g[i][0/1]表示当f[i][j]取最大值时最少的交易次数。

    贪心

    首先,如果a[i]=a[i+1],则可以删掉第i+1个商店。因为任何在第i+1个商店进行的交易都可以转为在第i个商店 进行,且收益不变。之后,如果a[i]<a[i+1],则离开第i个商店时一定要带上一件商品。如果a[i]>a[i+1],则离开 第i个商店时一定要空着手。这样,第一问的答案就为,第二问的答案就为长度>1的 极大递增连续段的数量。

    反正贪心就可以,按队友思路写的代码:

     1 //D-贪心
     2 #include<iostream>
     3 #include<cstdio>
     4 #include<cstring>
     5 #include<cmath>
     6 #include<algorithm>
     7 #include<queue>
     8 #include<stack>
     9 #include<map>
    10 #include<cctype>
    11 #include<cstdlib>
    12 
    13 typedef long long ll;
    14 const int maxn=1e5+10;
    15 const int inf=0x3f3f3f3f;
    16 const int mod=1e9+7;
    17 const double eps=1e-5;
    18 ll a[maxn];
    19 
    20 int main()
    21 {
    22     int t;
    23     scanf("%d",&t);
    24     while(t--){
    25         int n;
    26         scanf("%d",&n);
    27         for(int i=0;i<n;i++)
    28             scanf("%lld",&a[i]);
    29         a[n]=-1;
    30         ll sum=0,minn=a[0],maxx=a[0];
    31         int num=0,i=0;
    32         while(1){
    33             i++;
    34             if(i>n)break;
    35             if(a[i]<maxx){
    36                 if(maxx!=minn) num+=2;
    37                 sum+=maxx-minn;
    38                 maxx=minn=a[i];
    39             }
    40             maxx=std::max(maxx,a[i]);
    41         }
    42         printf("%lld %d
    ",sum,num);
    43     }
    44 }
  • 相关阅读:
    intellij常用快捷键
    C++ 虚函数详解
    第七周作业
    第六周作业
    第四周作业
    第三周作业
    第二周作业
    第一周作业附加作业
    第一周作业。
    第0次作业
  • 原文地址:https://www.cnblogs.com/ZERO-/p/9359346.html
Copyright © 2020-2023  润新知