1. 程式人生 > >hdu 6047 Maximum Sequence(貪心)

hdu 6047 Maximum Sequence(貪心)

you 貪心 string -i n+1 blog html next about

Description

Steph is extremely obsessed with “sequence problems” that are usually seen on magazines: Given the sequence 11, 23, 30, 35, what is the next number? Steph always finds them too easy for such a genius like himself until one day Klay comes up with a problem and ask him about it.

Given two integer sequences {ai} and {bi} with the same length n, you are to find the next n numbers of {ai}:
an+1a2nan+1…a2n. Just like always, there are some restrictions on an+1a2nan+1…a2n: for each number aiai, you must choose a number bkbk from {bi}, and it must satisfy aiai≤max{ajaj-j│bkbk≤j<i}, and any bkbk can’t be chosen more than once. Apparently, there are a great many possibilities, so you are required to find max{
2nn+1ai∑n+12nai} modulo 109109+7 .

Now Steph finds it too hard to solve the problem, please help him.

Input

The input contains no more than 20 test cases.
For each test case, the first line consists of one integer n. The next line consists of n integers representing {ai}. And the third line consists of n integers representing {bi}.
1≤n≤250000, n≤a_i≤1500000, 1≤b_i≤n.

Output

For each test case, print the answer on one line: max{2nn+1ai∑n+12nai} modulo 109109+7。 Sample
Sample Input
4
8 11 8 5
3 1 4 2 
 
Sample Output
27 

題意 :   這個題的題意是真不好理解啊,大體就是已知兩個數列a, b,已經給出了a, b的前n項,求數列a的n+1到2*n項,使得這些項的和最大

  數列要滿足aj <= max{ai - i},其中bk <= j < i,bk是數列b中的一項,且每個bk最多僅能取一次

  看到這裏肯定還看不明白。

  具體說一下第一個樣例:

    a數組是8 11 8 5   b數組是3 1 4 2  

    現在要擴充a數組,然後數組的擴充方法是,a數組中每個數等於本身減去他的下標,然後從b數組中選一個數,然後a數組的這個數的位置開始到最後選一個最大的(只能解釋到這樣了)。

    實現:a數組相當於 (8-1)(11-2)(8-3)(5-4)

    從b數組中選擇1,代表從a[1]到a[4]中選擇一個最大的,選擇9。然後將9添加到a數組中,然後數組為(8-1)(11-2)(8-3)(5-4) (9-5)

    然後第二次從b數組中選擇2代表從a[2]到a[5]中選擇一個最大的,選擇9。然後將9添加到a數組中,然後數組為(8-1)(11-2)(8-3)(5-4) (9-5)(9-6)

    然後第三次從b數組中選擇3代表從a[3]到a[6]中選擇一個最大的,選擇5。然後將5添加到a數組中,然後數組為(8-1)(11-2)(8-3)(5-4) (9-5)(9-6)(5-7)

    然後第四次從b數組中選擇4代表從a[4]到a[7]中選擇一個最大的,選擇4。然後將9添加到a數組中,然後數組為(8-1)(11-2)(8-3)(5-4) (9-5)(9-6)(5-7)(4-8)

  然後更新完成了。最後數列a的n+1到2*n項的值為9+9+5+4=27

思路:

要想使數列a的n+1到2*a項最大,又每項都要減去i

所以應該盡量使bk最小,從最前面開始(可以理解為貪心)

那麽肯定要先把最大的放進來

將b排序,計算ai - i的值

開一個max數組記錄從i 到最後一項的最大ai-i的值(可以從後往前找)

每次加入點的時候,從後往前比較,如果小於這個數,就更新為這個數。

用一個sum記錄總和。

記得每次加的結果要%mod。

註意數組要開為數據量的兩倍,因為a數組要擴展!

代碼:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
int mod=1e9+7;
using namespace std;
int a[500010],b[500010],maxx[500010];
int main()
{
    int n;
    while(~scanf("%d",&n))
    {
        memset(maxx,0,sizeof(maxx));
        for(int i=1; i<=n; i++)
        {
            scanf("%d",a+i);
            a[i]-=i;
        }
        for(int i=1; i<=n; i++)
        {
            scanf("%d",b+i);
        }
        sort(b+1,b+n+1);
        maxx[n]=a[n];
        for(int i=n; i>=2; i--)//更新max數組
        {
            maxx[i-1]=max(a[i-1],maxx[i]);
        }
        int flag=n+1;
        int sum=0;
        for(int i=1; i<=n; i++)
        {
            sum+=maxx[b[i]];//選擇最大的數
            a[flag]=maxx[b[i]]-(flag);
            maxx[flag]=a[flag];
            for(int j=flag-1; j>=1; j--)//加入新的點之後,要更新對應的max
            {
                if(maxx[j]<maxx[flag])
                    maxx[j]=maxx[flag];
                else break;
            }
            flag++;
            sum=sum%mod;
        }
        printf("%d\n",sum);
    }
}

hdu 6047 Maximum Sequence(貪心)