問題への2019頭の牛オフ以上の学校最初のフィールドE ABBA(DP)ソリューション

問題の意味:AとB、nとmのBAシーケンスのAB必要なシーケンス番目(M + N)の文字列で、あなたに2 *(N + M)の長さを聞いて、いくつかのような文字列があります

https://ac.nowcoder.com/acm/contest/881/E

アイデア:

その後明らかに、AB Aの最初のn個のAのためのBA BのBなければならない最初のmが存在するであろう、nおよびm AB BAのためのサブ配列、有効な文字列があると 私はAのBAがある最初のn Aであった場合、私は明らかに、その後、最初のn AのAB用マスト簡単にして、より後ろからBまでを見つけることができなかったため

我々は、i番目のAjとBのための[i]の[j]のDPを想定してみましょう:

私はそれが直接Aを配置することができる<Nであれば、上記の理由

N - (Iように、N - 私は> = N、我々はA及びBは、正面とBAを与える場合、現在必要なBA Aは分(J、M)数であり、彼は私を与えていることを確認する必要がある場合)<分(J、M)を排出し続けることができます。

コード:

#include <cmath> 
の#include < 設定 > 
の#include <地図> 
の#include <キュー> 
の#include <cstdioを> 
する#include <ベクトル> 
の#include <CStringの> 
する#include <iostreamの> 
する#include <アルゴリズム>
 使用して 名前空間STD。
typedefの長い 長いLL。
typedefの符号なしの長い 長いULL。
const  int型 MAXN = 2E3 + 5 const  int型 M = 50 + 5 constの ULLシード=131 const  int型 INF = 0x3f3f3f3f const  int型 MOD = 1E9 + 7 
LL DP [MAXN] [MAXN]。
INT のmain(){
     int型N、M。
    しながら(〜のscanf(" %d個の%のD "、&​​N、&M)){
         ためint型 I = 0 ; iがM <= N +; iが++ ){
             ためINT J = 0 ; J <= N + M。 J ++ ){ 
                DP [I] [J] = 0 ; 
            } 
        }
        DP [ 0 ] [ 0 ] = 1 以下のためにint型 i = 0 ; iが<= N + Mは、iが++ ){
             ためのint型 J = 0 ; J <= N + M; J ++ ){
                 場合(iがn <||(I - N)<J){    // プッシュ 
                    DPを[I + 1 ] [j] =(DP [I + 1 ] [J] + DP [I] [J])%MOD。
                } 
                であれば(J <M ||(J - M)<I){    // プッシュBの 
                    DP [I]、[J + 1 ] =(DP [I] [J + 1 ] + DP [I] [J]) %MOD。
                } 
            } 
        } 
        のprintf(" %LLDする\ n "、DP [N + M] [N + M])。
    } 
    戻り 0 
}

 

おすすめ

転載: www.cnblogs.com/KirinSB/p/11209560.html