უგრძესი საერთო ქვემიმდევრობის ამოცანა

გვერდიდან testwiki
ნავიგაციაზე გადასვლა ძიებაზე გადასვლა

უგრძესი საერთო ქვემიმდევრობის (უსქ) ამოცანა — ამოცანა, რომელიც ეძებს მიმდევრობებს შორის უგრძეს საერთო ქვემიმდევრობას (ძირითადად ორ მიმდევრობაზე განიხილავენ).

მაგალითად, განვიხილოთ ორი მიმდევრობა (ABCD) და (ACBAD). მათ 5 უსქ აქვთ, სიგრძით 2: (AB),(AC),(AD),(BD) და (CD); 2 უსქ, სიგრძით 3: (ABD) და (ACD); უფრო გრძელი კი არ გვაქვს. შესაბამისად, (ABC) და (ACD) არის უგრძესი საერთო ქვემიმდევრობა.

სირთულე

ეს ამოცანა არის NP-რთული ამოცანა. ის დინამიური პროგრამირების პრინციპით პოლინომიურ დროში იხსნება.[1]

მოცემულია N სიგრძეების მიმდევრობები n1,...,nN, სრული ძებნა შეამოწმებს თითოეულ მათგანის 2n1 ქვესიმრავლეს, რათა დაადგინოს, არიან თუ არა ისინი აგრეთვე დანარჩენი მიმდევრობების ქვემიმდევრობები; მოცემული ამოცანის დროის სირთულე იქნება

O(2n1i>1ni).

n და m სიგრძის ორი მიმდევრობისთვის დროის სირთულე დინამიური პროგრამირებით იქნება O(n × m).[2] ნებისმიერი რაოდენობის ქვემიმდევრობისთვის დინამიური პროგრამირების ამოხსნის დროის სირთულე იქნება

O(Ni=1Nni).

ამოხსნა ორი მიმდევრობისთვის

თარგი:წყარო

LCS ფუნქცია

განვსაზღვროთ ორი მიმდევრობა შემდეგნაირად: X=(x1x2xm) და Y=(y1y2yn) . X-ის პრეფიქსები არიან X1,2,,m ; Y-ის კი Y1,2,,n .𝐿𝐶𝑆(Xi,Yj) -ით აღვნიშნოთ უგრძესი საერთო ქვემიმდევრობა პრეფიქსებისთვის Xi და Yj .

𝐿𝐶𝑆(Xi,Yj)={თუ i=0 ან j=0𝐿𝐶𝑆(Xi1,Yj1)+1თუ i,j>0 და xi=yjmax{𝐿𝐶𝑆(Xi,Yj1),𝐿𝐶𝑆(Xi1,Yj)}თუ i,j>0 და xiyj.

რათა ვიპოვოთ LCS Xi და Yj-თვის, შევადაროთ xi და yj. თუ ისინი ტოლია, მაშინ ქვემიმდევრობა 𝐿𝐶𝑆(Xi1,Yj1) -ზე ერთით მეტი იქნება . თუ ისინი ტოლი არ არიან, მაშინ 𝐿𝐶𝑆(Xi,Yj1), და 𝐿𝐶𝑆(Xi1,Yj) შორის უგრძესის ტოლი გახდება.

იმპლემენტაცია C++-ზე

int dp[1000][1000];
int getLCS(vector<int>a,vector<int>b){
    int n=a.size();
    int m=b.size();
    for(int i=1; i<=n; i++){
        for(int j=1; j<=m; j++){
            if(a[i-1]==b[j-1]){
                dp[i][j]=1+dp[i-1][j-1];
            }else{
                dp[i][j]=max(dp[i-1][j],dp[i][j-1]);
            }
        }
    }return dp[n][m];
}

რესურსები ინტერნეტში

სქოლიო

თარგი:სქოლიო