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 long
using 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;
}