wustoj 1583: Sharing! 思维

来源:互联网 发布:scd数据库期刊 编辑:程序博客网 时间:2024/06/05 16:09

题意:一个数列,找出两个数a[i], a[j],使得s = max(|j - i| * min(a[i], a[j]))最大,求最大值。

要求:n<=1e6,使用O(nlogn)算法会超时。

解法:f(le,ri):

          对于一个区间[le,ri],先用le和ri更新答案

         维护两个指针一个指向le,一个指向ri,现在将指向小元素的指针向另一边移动,

         中间遇见元素a[p],

        如果a[p]<min(a[le],a[ri]),忽略。

         否则答案=f(p,ri)(如果a[le]<a[ri]) || f(le,p) (如果a[le]>=a[ri])

                  



#include<cstdio>#include<string>#include<cstring>#include<iostream>#include<cmath>#include<algorithm>#include<vector>using namespace std;#define all(x) (x).begin(), (x).end()#define for0(a, n) for (int (a) = 0; (a) < (n); (a)++)#define for1(a, n) for (int (a) = 1; (a) <= (n); (a)++)typedef long long ll;typedef pair<int, int> pii;const int INF =0x3f3f3f3f;const int maxn=1000000    ;ll ans;int n,a[maxn+10];void cope(int le,int ri){    ans=max(ans,(ll)(ri-le)*min(a[ri],a[le]) );    switch(a[le]>a[ri])    {        case true:        for(int p=ri-1;p>le;p--)        {            if(a[p]<=a[ri])  continue;            else            {                cope(le,p);                return;            }        }        case false:        for(int p=le+1;p<ri;p++)        {            if(a[p]<=a[le]) continue;            else            {                cope(p,ri);                return;            }        }    }}int main(){    int T;scanf("%d",&T);    while(T--)    {        scanf("%d",&n);        for1(i,n)        {            scanf("%d",&a[i]);        }        ans=0;        cope(1,n);        printf("%lld\n",ans);    }   return 0;}


0 0
原创粉丝点击