hdu5696区间的价值 -- 2016"百度之星" - 初赛(Astar Round2B)

Problem Description

我们定义“区间的价值”为一段区间的最大值*最小值。

一个区间左端点在L,右端点在R,那么该区间的长度为(R−L+1)。

现在聪明的杰西想要知道,对于长度为k的区间,最大价值的区间价值是多少。

当然,由于这个问题过于简单。

我们肯定得加强一下。

我们想要知道的是,对于长度为1∼n的区间,最大价值的区间价值分别是多少。

样例解释:

长度为1的最优区间为2−2 答案为6∗6

长度为2的最优区间为4−5 答案为4∗4

长度为3的最优区间为2−4 答案为2∗6

长度为4的最优区间为2−5 答案为2∗6

长度为5的最优区间为1−5 答案为1∗6

Input

多组测试数据

第一行一个数n(1≤n≤100000)。

第二行n个正整数(1≤ai≤10^9),下标从1开始。

由于某种不可抗力,ai的值将会是1∼10^9内随机产生的一个数。(除了样例)

Output

输出共n行,第i行表示区间长度为i的区间中最大的区间价值。

Sample Input

5

1 6 2 4 4

Sample Output

36

16

12

12

6

 

看见那鲜红的随机产生了吗?显然这是突破口(当时看着很多人A然而并没有想出来

其实对于随机数据,有些暴力的效率很高

我们枚举每一个点作为区间的最大值(所以大于这个值的都不能取),然后向两边扩展,扩展的顺序是将较大者加入区间,边做边更新答案

贪心的正确性算比较显然吧,较大值加进来肯定比较小值加进来优,因为最大值已经固定了,我们要让最小值最大

 1 #include<cstdio>
 2 using namespace std;
 3 
 4 int a[100100],n;
 5 long long ans[100100];
 6 
 7 void work()
 8 {
 9     for(int i = 1;i <= n;i++)
10         scanf("%d",&a[i]);
11     for(int i = 1;i <= n;i++)
12         ans[i]=0;
13     
14     for(int i = 1;i <= n;i++)
15     {
16         long long max=a[i],min=a[i];
17         int len=1,l=i,r=i;
18         while(1)
19         {
20             if(ans[len]<max*min)ans[len]=max*min;
21             if(l==1 || a[l-1]>max)
22                 if(r==n || a[r+1]>max) break;
23                 else
24                 {
25                     r++;
26                     len++;
27                     if(a[r]<min)min=a[r];
28                 }
29             else
30                 if(r==n || a[r+1]>max)
31                 {
32                     l--;
33                     len++;
34                     if(a[l]<min)min=a[l];
35                 }
36                 else
37                 {
38                     if(a[l-1]>a[r+1])
39                     {
40                         l--;
41                         len++;
42                         if(a[l]<min)min=a[l];
43                     }
44                     else
45                     {
46                         r++;
47                         len++;
48                         if(a[r]<min)min=a[r];
49                     }
50                 }
51         }
52     }
53     
54     for(int i = 1;i <= n;i++)
55         printf("%I64d\n",ans[i]);
56 }
57 
58 int main(){
59     while(scanf("%d",&n)!=EOF)
60         work();
61     return 0;
62 }
AC代码

 

 

转载于:https://www.cnblogs.com/Randolph87/p/5528112.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值