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 }
本文来自博客园,作者:江上舟摇,转载请注明原文链接:https://www.cnblogs.com/LQS-blog/p/15894341.html