贪心

来源:互联网 发布:手机修改图片软件 编辑:程序博客网 时间:2024/06/04 22:37

Maximum Sequence

Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)

题意:给两个长度为n的序列a, b,现要求max(sum(a[n + 1] + … + a[2n])),其中a[i] = max(a[b[k]] … a[i - 1]),其中b[k]为b[1 … n]中的一个,每个a[i]选择的b[k]不能重复

思路:贪心,我们肯定是从最前面开始,最大的值放进来,对后面好处也更大


相当于给定区间,求区间的最值和。一般求变化的区间经常用线段树来做,但是这里可以不用线段树。

将代表下标的b数组排序一遍,从小到大更有利于贪心。对A数组进行预处理,从后往前,a[i]=max( a[i+1],a[i] ),然后维护后面新加入的最大值就可以了。


#include <iostream>#include <stdio.h>#include <string.h>#include <algorithm>#define LL long longusing namespace std;const int ma=250010;const LL mod=1e9+7;int a[ma],b[ma];int main(){    int n;    while(scanf("%d",&n)!=EOF)    {        int x;        for(int i=1;i<=n;++i)        {            scanf("%d",&x);            a[i]=x-i;        }        for(int i=n-1;i>0;--i)            a[i]=max(a[i+1],a[i]);        for(int i=1;i<=n;++i)            scanf("%d",&b[i]);        sort(b+1,b+n+1);        LL ans=0;        int most=-1,kk;        for(int i=1;i<=n;++i)        {            kk=max(most,a[b[i]]);            ans=(ans+kk)%mod;            most=max(kk-n-i,most);        }        printf("%lld\n",ans);    }    return 0;}








原创粉丝点击