第一章例题18开放式学分制UVa11078

来源:互联网 发布:淘宝上的评论怎么删除 编辑:程序博客网 时间:2024/05/01 18:08

 

 

 

/*此题最简单的想法就是:
用两个for循环计算不同的两个数组元素的差值,再从中挑选出最大值
但是此法虽简单,但是时间复杂度为O(n^2),对于n=100000妥妥的超时*/

/*咋办呢,看看刘汝佳的办法吧,我可没想出来啊
对于某一个下标为j的元素,我们只要用j前面的所有的i元素中的最大值减去j元素,就得到了相对于j的结果最大的值
在所有的j的结果的最大值中再选出最大的就ok了,
实际上可以看出我们的主要任务是维持住j前面的所有i中的最大值,这样算法的时间复杂度变成了O(n)*/

/*ans不可以设定为0,因为我们知道答案可能为负数,ans是理想中的最大值,如果ans初值设为0,
由于ans的更新是由大小关系if(ans<...)来判断的,只有遇见比它大的才会更新,如果某一组数据的
正确结果为负数,是不会更新的,这就导致ans肯定是非负数,所以这样做是错误的。
我们有两种方法可以设定ans的初值:
法一:由输入数据求出一个确切存在的某个ans的值
法二:在估计范围内,选取一个极限值来初始化
   极限值的选取规则是:在估计值的范围内,
   如果要求的是最大值,则可以初始化为一个特别小的值,具体是0还是负无穷大依题而定
   如果要求的是最小值,则可以初始化为一个特别大的值,可以初始化为正无穷大
*/

/*在写无穷大和无穷小的时候不要用INT_MAX之类的宏*/

#include<iostream>
#include<cstdio>
using namespace std;
const int maxn=100010;
int data[maxn];
int n,maxi,ans;//maxi是要维持的j前面的所有i中的最大值,ans为最终要求的结果
int main()
{
 int t,i;
 cin>>t;
 while(t--)
 {
  cin>>n;
  for(i=0;i<n;i++)
  {scanf("%d",&data[i]);}
  maxi=-200000;/*maxi不可以设定为0,因为由题意数据元素可以为负值,坑死我了都*/
  ans=-500000;
  for(i=1;i<n;i++)
  {
   if(maxi<data[i-1])
   {maxi=data[i-1];}
   if(ans<maxi-data[i])
   {ans=maxi-data[i];}
  }
  cout<<ans<<endl;
 }
 return 0;
}

 

0 0
原创粉丝点击