笨蛋难题四
时间限制:1000 ms | 内存限制:65535 KB
难度:3
-
描述
-
这些日子笨蛋一直研究股票,经过调研,终于发现xxx公司股票规律,更可喜的是 笨蛋推算出这家公司每天的股价,为了防止别人发现他的秘密。他决定对于这家公司的 股票最多买一次,现在笨蛋已经将股票价格列了出来。(这已经不是笨蛋的难题了,他已经解决 呵 呵)。只想难为难为你呀,从股票价格表上,你能算出笨蛋的每股股票最多能赚多少钱吗?
-
输入
- 第一行一个n,表示n天(小于100000)
第二行 给出n天每股的价格
输出 - 每股最多赚多少钱 样例输入
-
4 947 267 359 771 7 669 735 322 794 397 565 181
样例输出 -
504 472
- 第一行一个n,表示n天(小于100000)
可以用很“笨蛋“ 的方法,线段树,方法确实很笨蛋,哈哈,不过全当是练习线段树了
#include<algorithm>
#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
using namespace std;
const int M=1e5+5;
int tree[4*M],a[M];
void build(int l, int r, int root){
if(l == r){
scanf("%d",&tree[root]);
a[l] = tree[root];
return ;
}
int mid =(l+r)/2;
build(l, mid, root*2);
build(mid+1, r, root*2+1);
tree[root] = max(tree[ root * 2 ],tree[root * 2 + 1]);
}
int query(int l ,int r, int L, int R, int root){//在L--R中 查询l--r中的最大值
if(l == L && r == R)return tree[root];
int mid= (L + R)/2;
if(r < mid)return query(l, r, L, mid-1, root*2);
else if(mid < l ) return query(l, r, mid+1, R, root*2+1);
else return max(query(l, mid, L, mid,root*2),query(mid + 1 , r, mid+1, R,root*2+1));
}
int main()
{
//freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout);
int n;
while( scanf("%d",&n) == 1){
memset(tree,0,sizeof(tree));
build(1, n, 1);
int res=0;
for(int i=1; i<=n; i++){
res =max(res, query(i+1, n, 1, n, 1)-a[i]);
}
cout<<res<<endl;
}
return 0;
}
然后可以发现,稍微聪明一点的方法:直接保存 后面i--n 项的最大值:类似于RMQ算法
#include<algorithm>
#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
using namespace std;
const int M=1e5+10;
int a[M],b[M];
int main()
{
//freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout);
int n,i,j;
while(scanf("%d",&n) == 1){
for(i=0; i<n; i++){
scanf("%d", &a[i]);
}
b[n-1]=a[n-1];
for(i=n-2; i>=0; i--){
b[i] = max(a[i],b[i+1]);
}
int maxi=-1;
for(i=0; i<n; i++){
if(b[i]-a[i]>maxi)maxi=b[i]-a[i];
}
cout<<maxi<<endl;
}
return 0;
}