2017 Multi-University Training Contest - Team 2 C - Maximum Sequence

题意:给定两个数组 a,b;现在需要构造a数组 n+1~ 2n 的项;
要求: 在 bk <= j < i 的前提下, ai =Max { aj - j } ;
现在求出Σ ai , i from n+1 to 2n 的最大值;

思路: 贪心; 怎么贪心呢? 不妨这么考虑,由于选的要减去 i ;所以 bk 肯定尽量小,那么我们将b数组排序,每次取前面的而且没有取过的即可,同时维护一下 i ~ end 的最大值即可

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstdlib>
#include<cstring>
#include<string>
#include<cmath>
#include<map>
#include<set>
#include<vector>
#include<queue>
#include<string>
#include<bitset>
#include<ctime>
#include<deque>
#include<stack>
#include<functional>
#include<sstream>
using namespace std;
typedef long long ll;
#define maxn 500005
const int mod=1e9+7;
#define inf 0x3f3f3f3f
#define ms(x) memset(x,0,sizeof(x))

void exgcd(ll a,ll b,ll &d,ll &x,ll &y)
{
    if(b==0){
        x=1;y=0;d=a;
    }
    else {
        exgcd(b,a%b,d,y,x);
        y-=x*(a/b);
    }
}
int a[maxn],b[maxn];
int Max[maxn];

int main()
{
    ios::sync_with_stdio(false);
    int n;
    while(cin>>n){
        int i,j;
        ms(Max);
        for(i=1;i<=n;i++){
            cin>>a[i];a[i]-=i;
        }
        for(i=1;i<=n;i++){
            cin>>b[i];
        }
        sort(b+1,b+1+n);
        Max[n]=a[n];
        for(i=n;i>=2;i--){
            Max[i-1]=max(Max[i],a[i-1]);
        }
        int tt=n+1;
        int sum=0;
        for(i=1;i<=n;i++){
            sum+=Max[b[i]];
            a[tt]=Max[b[i]]-tt;
            Max[tt]=a[tt];

            for(j=tt-1;j>=1;j--){
              //  Max[j]=max(Max[j],Max[tt]);
                if(Max[j]<Max[tt]){
                    Max[j]=Max[tt];
                }
                else break;
            }
            tt++;
            sum%=mod;
        }
        cout<<sum<<endl;
    }
}





猜你喜欢

转载自blog.csdn.net/qq_40273481/article/details/81748103