给定一个数组序列, 需要求选出一个区间, 使得该区间是所有区间中经过如下计算的值最大的一个:
区间中的最小数 * 区间所有数的和最后程序输出经过计算后的最大值即可,不需要输出具体的区间。如给定序列 [6 2 1]则根据上述公式, 可得到所有可以选定各个区间的计算值:
[6] = 6 * 6 = 36;
[2] = 2 * 2 = 4;
[1] = 1 * 1 = 1;
[6,2] = 2 * 8 = 16;
[2,1] = 1 * 3 = 3;
[6, 2, 1] = 1 * 9 = 9;
从上述计算可见选定区间 [6] ,计算值为 36, 则程序输出为 36。
区间内的所有数字都在[0, 100]的范围内;
输入描述:
第一行输入数组序列长度n,第二行输入数组序列。 对于 50%的数据, 1 <= n <= 10000; 对于 100%的数据, 1 <= n <= 500000;
输出描述:
输出数组经过计算后的最大值。
输入例子1:
3 6 2 1
输出例子1:
36
思路一:最开始第一眼看到区间,线段树,两个数组,一个记录最小值,一个记录区间和,但是看到了500000.。。。依然勇敢的码了一发上去(反正随便测。。) 果然只有30%的通过率,贴上代码
#include<bits/stdc++.h>
using namespace std;
#define maxn 500004
int a[maxn],st[maxn];//维护最小值的线段树
int tr[maxn];//维护区间和的线段树
void build(int o,int l,int r)
{
if( l == r ) st[o] = a[l],tr[o] = a[l];
else
{
int m = (l+r)>>1;
build(o<<1,l,m);
build(o<<1|1,m+1,r);
st[o] = min(st[o<<1],st[o<<1|1]);
tr[o] = tr[o<<1] + tr[o<<1|1];
}
}
int query(int L,int R,int l,int r,int o,int k)
{
if (L<=l&&r<=R)
{
if(k == 0)
return st[o];
else return tr[o];
}
int mid=(l+r)>>1;
int ans = 0;
int minn = 999999999;
if (L<=mid && k == 1) ans+=query(L,R,l,mid,o<<1,1);
if (R>mid && k == 1) ans+=query(L,R,mid+1,r,o<<1|1,1);
if (L<=mid && k == 0) minn=min(minn,query(L,R,l,mid,o<<1,0));
if (R>mid && k == 0) minn=min(minn,query(L,R,mid+1,r,o<<1|1,0));
if(k == 1)
return ans;
else return minn;
}
int main()
{
int n;
int maxx = -1;
scanf("%d",&n);
for(int i=1; i<=n; i++)
scanf("%d",&a[i]);
build(1,1,n);
for(int i=1; i<=n; i++)
{
for(int j=i; j<=n; j++)
{
int minn = query(i,j,1,n,1,0);
int sum = query(i,j,1,n,1,1);
maxx = max(maxx,minn*sum);
}
}
printf("%d\n",maxx);
}
思路二:看到了所有数据都是在区间[0,100[,因此可以把每个点都当成最小值,然后想左向右寻找边界,也就是第一个小于位置的数,虽然感觉数据应该也很大,但是竟然通过了。。。
#include<bits/stdc++.h>
using namespace std;
#define maxn 500004
int a[maxn];
int main()
{
int n;
scanf("%d",&n);
for(int i=0; i<n; i++)
scanf("%d",&a[i]);
int maxx = -1;
for(int i=0; i<n; i++)
{
//左
int ans =0 ;
for(int j=i; j>=0; j--)
{
if(a[i]<=a[j])
ans+=a[j];
else break;
}
//右
for(int j=i+1; j<n; j++)
{
if(a[i]<=a[j])
ans+=a[j];
else break;
}
maxx = max(maxx,ans*a[i]);
}
printf("%d\n",maxx);
return 0;
}
简单粗暴。。。。