HDU6047(数学题)

来源:互联网 发布:数据研究中心美国大学 编辑:程序博客网 时间:2024/06/09 13:05

给你两个长度为n的数列,a,b;
然后根据下列公式计算an+1,an+2...a2n,并使他们的和最大,最后输出他们的最大和.

ai=max{abin,abin+1,...ai1}2n<i<=2n

这里区间最大值要用O(1)的算法,不然会超时,难受
首先要给b排序,这样才能保证和最大
我们将abin,abin+1,...ai1,分成两部分,
一部分为abin,abin+1,...an
另一部分abn,abn+1,...ai1
比较两部分的最大值赋值给ai

code:

#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>using namespace std;int a[500005];int b[500005];const int mod=1000000007;int main(){    int n;    int i,j,k;    int ans;    while(scanf("%d",&n)!=EOF)    {        ans=0;        for(i=1;i<=n;i++)        {            scanf("%d",&a[i]);            a[i]=a[i]-i;        }        for(i=n-1;i>=1;i--)        {            if(a[i]<a[i+1])                a[i]=a[i+1];        }        for(i=1;i<=n;i++)        {            scanf("%d",&b[i]);        }        sort(b+1,b+n+1);        k=n+1;        for(i=1;i<=n;i++)        {            ans+=a[b[i]];            a[k]=a[b[i]]-k;            for(j=k-1;j>=1;j--)            {                if(a[k]>a[j])                    a[j]=a[k];                else                    break;            }            /*for(j=1;j<=k;j++)            {                cout<<"a["<<j<<"] = "<<a[j]<<endl;            }            cout<<"------------"<<endl;*/            k++;            ans%=mod;        }        cout<<ans<<endl;    }    return 0;}