• jzoj4762. 千帆渡


    Description

    在这里插入图片描述

    Input

    在这里插入图片描述

    Output

    在这里插入图片描述

    Sample Input

    输入1:
    5
    1 4 2 5 1
    4
    1 1 2 4
    输入2:
    见共享

    Sample Output

    输出1:
    2
    1 4
    输出2:
    见共享

    Data Constraint

    在这里插入图片描述

    题解

    此题是一道奇妙的题目。
    由于各种原因,本题开捆绑数据,我想原因是为了防止大家水分水特别高。
    所以我比赛时爆零了
    正解真的要大开脑洞才行。
    首先当然想到的是DP
    设f[i,j]表示前i个红色的船,当前选到第j个蓝色的船的最大答案。
    设g[i,j]表示上述情况下时,上一个蓝色的船是什么。
    这样就可以边转移边记录答案了。
    转移方程——
    f[i,j]:=max(f[i1,k]+1);g[i,j]:=k;[a[i]=b[j]]f[i,j]:=max(f[i-1,k]+1);g[i,j]:=k;[a[i]=b[j]]
    f[i,j]:=f[i1,j];g[i,j]:=j;[a[i]<>b[j]]f[i,j]:=f[i-1,j];g[i,j]:=j;[a[i]<>b[j]]
    这样能够拿到45分的好成绩。

    那么考虑优化。
    由于这个k我们看起来很烦,那么考虑把一些冗杂的状态给减去。
    我们设h[i,j]表示当前a[i]=b[j]时的f[i,j]状态下,由h[i,j]转移过来。
    可以把h[i,j]想象成一个最优的k。
    那么,每次在做完f[i,j]后,用当前的h[i+1,j-1]转移到h[i+1,j]即可。
    具体就是分两类讨论——
    1、当b[j]<a[i+1]且f[i,h[n+1,j-1]]<f[i,j]时,就更新h[i+1,j]=j
    2、否则就是h[i+1,j]=h[i+1,j-1]
    好好理解就懂了。

    代码

    {$inline on}
    var
            i,j,k,l,n,m,ans,x,y,wz,gs,op,maxx,ni:longint;
            a,b,bb,id,ad,bd:array[0..5000] of longint;
            sum,map:array[1..5000,0..5000] of longint;
            f,g,h:array[0..5000,0..5000] of longint;
            answer:array[0..5000] of longint;
    
    procedure qsort(l,r:longint);inline;
    var
            i,j,k,m:longint;
    begin
            i:=l;j:=r;
            m:=b[(l+r) div 2];
            repeat
                    while b[i]<m do inc(i);
                    while b[j]>m do dec(j);
                    if i<=j then
                    begin
                            k:=b[i];
                            b[i]:=b[j];
                            b[j]:=k;
                            k:=id[i];
                            id[i]:=id[j];
                            id[j]:=k;
                            inc(i);
                            dec(j);
                    end;
            until i>j;
            if l<j then qsort(l,j);
            if r>i then qsort(i,r);
    end;
    function erfen(id,x,y:longint):longint;inline;
    var
            l,r,mid:longint;
    begin
            l:=x;
            r:=y;
            while l<r do
            begin
                    mid:=(l+r)div 2;
                    if sum[id,x]=sum[id,mid] then l:=mid+1 else r:=mid;
            end;
            erfen:=l;
    end;
    begin
            //assign(input,'qfd.in');reset(input);
            //assign(input,'0data.in');reset(input);
            readln(n);
            for i:=1 to n do
            begin
                    read(a[i]);
            end;
            readln(m);
            for i:=1 to m do
            begin
                    read(b[i]);
            end;
            for i:=1 to n do
            begin
                    for j:=1 to m do
                    begin
                            if a[i]=b[j] then
                            begin
                                    //for k:=0 to j-1 do
                                    begin
                                            if (b[h[i,j]]<b[j]) and (f[i,j]<f[i-1,h[i,j]]+1) then
                                            begin
                                                    f[i,j]:=f[i-1,h[i,j]]+1;
                                                    g[i,j]:=h[i,j];
                                            end;
                                    end;
                            end
                            else
                            begin
                                    f[i,j]:=f[i-1,j];
                                    g[i,j]:=j;
                            end;
    
                            ni:=i+1;
                            if b[j]<a[ni] then
                            begin
                                    if f[i,h[ni,j-1]]>=f[i,j] then
                                    begin
                                            h[ni,j]:=h[ni,j-1];
                                    end
                                    else
                                    begin
                                            h[ni,j]:=j;
                                    end;
                            end
                            else
                            begin
                                    h[ni,j]:=h[ni,j-1];
                            end;
                    end;
            end;
            for i:=1 to n do
            begin
                    for j:=1 to m do
                    begin
                            if ans<f[i,j] then
                            begin
                                    x:=i;
                                    y:=j;
                                    ans:=f[i,j];
                            end;
                    end;
            end;
            writeln(ans);
            while x>0 do
            begin
                    if a[x]=b[y] then
                    begin
                            inc(answer[0]);
                            answer[answer[0]]:=a[x];
                    end;
                    y:=g[x,y];
                    x:=x-1;
            end;
            for i:=answer[0] downto 1 do
            begin
                    write(answer[i],' ');
            end;
            writeln;
    end.
    
    我活在这夜里。无论周围多么黑暗,我都要努力发光!我相信着,终有一天,我会在这深邃的夜里,造就一道最美的彩虹。
  • 相关阅读:
    [HDOJ1261]最少拦截系统
    Gym 100637F F. The Pool for Lucky Ones
    Codeforces Gym 100637A A. Nano alarm-clocks 前缀和处理
    HDU 1166 敌兵布阵 线段树
    【Tyvj1038】忠诚 线段树
    Codeforces Gym 100513G G. FacePalm Accounting
    Codeforces Round #313 (Div. 2)B.B. Gerald is into Art
    Codeforces Round #313 (Div. 2) D. Equivalent Strings
    Codeforces Round #313 (Div. 2) C. Gerald's Hexagon 数学
    Codeforces Round #313 (Div. 2) A. Currency System in Geraldion
  • 原文地址:https://www.cnblogs.com/RainbowCrown/p/11148374.html
Copyright © 2020-2023  润新知