SDMU OJ#P19. 股票买卖

Description

七七是一个炒股的爱好者,整日痴迷与炒股,但是由于七七数学不好,需要你帮助他算出炒股获得的最大利润是多少。现在给定一个长度为 N 的数组,数组中的第 i 个数字表示一个给定股票在第 i 天的价格。如果最多只允许完成一笔交易(即买入和卖出一支股票),设计一个算法来计算七七所能获取的最大利润。注意你不能在买入股票前卖出股票(如果不进行任何交易, 最大利润为 0)。由于七七是一个非常会股票买卖的的人,七七最终获得的利润是原来获得利润的100倍,如果七七最终获得的利润小于1e18,则输出获得的利润,否则输出“fa cai le!”。

Input

第一行包含整数 NNN,表示数组长度。第二行包含 NNN 个不大于 1e18 的正整数,表示完整的数组。(1<=N<=100000)

Output

如果七七最终获得的利润小于1e18,则输出获得的利润,否则输出“fa cai le!”。

Sample

Input 1

5
46 49 49 35 48

Output 1

1300

Input 2

2
1 1000000000000000000

Output 2

fa cai le!

Hint

时间限制:1000ms

内存限制:65536KiB

这个题无非就是求最大差,有两种思路:

1.贪心:

j>i,找出所有区间中最大的a[j]-a[i],最后按照题目要求输出,参考代码如下:

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 long long  a[100010];
 4 int n;
 5 long long ans; 
 6 int main()
 7 {
 8     ios::sync_with_stdio(false);
 9     cin>>n;
10     for(int i=1;i<=n;i++)
11     cin>>a[i];
12         for(register int i=1;i<=n;i++) 
13         {
14             for(register int j=i+1;j<=n;j++)
15             {
16                 ans=max(ans,a[j]-a[i]);
17             }
18         }
19         if(ans*100<1e18)
20         cout<<ans*100;
21         else
22         cout<<"fa cai le!";
23     return 0;
24 }

下一种方法是dp,我们让dp【i】表示前i天最小的股票价值,就相当于找到了起点,

要求最大利润,即a[j]-a[i]最大并且i < j. 如果我们能知道前j个元素中的最小值,就可以找到买股票的起点。因此令dp[i]表示前i个元素中的最小值,可以得到这样的状态转移方程:
dp[1] = a[1],dp[i] = min(a[i], dp[i-1]).
那么a[i] - dp[i]就代表着前i个元素中的最大利润。我们枚举i,找到最大的i使得a[i]-dp[i]最大即可。

参考代码如下:

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 long long dp[100010];//前i个元素中最小值 
 4 long long a[100010];
 5 int n;
 6 long long ans;
 7 int main()
 8 {
 9     ios::sync_with_stdio(false);
10     cin>>n;
11     for(int i=1;i<=n;i++)
12     cin>>a[i];
13     dp[1]=a[1];//初始化 
14     for(int i=2;i<=n;i++)
15     {
16         dp[i]=min(dp[i-1],a[i]);//转移方程 
17         ans=max(ans,a[i]-dp[i]);//当前ans的值和当前股票的价值与最小股票值之差谁大,开始枚举 
18     }
19     if(ans*100<1e18)
20     cout<<ans*100;
21     else
22     cout<<"fa cai le!";
23     return 0;
24 }

 

posted @ 2022-02-14 22:01  江上舟摇  阅读(118)  评论(2编辑  收藏  举报