1. Trang chủ
  2. » Công Nghệ Thông Tin

Quy hoạch động Bài toán Palindrome

3 2,1K 59

Đang tải... (xem toàn văn)

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Định dạng
Số trang 3
Dung lượng 25,02 KB

Nội dung

Tài liệu bồi dưỡng học sinh giỏi THPT – Môn Tin học Phần II: Chuyên đề nâng caoCHUYÊN ĐỀ NÂNG CAO 6 CHUYÊN ĐỀ 6: QUY HOẠCH ĐỘNG D.. BÀI TOÁN XÂU PALINDROME XÂU ĐỐI XỨNG Palindrome hay cò

Trang 1

Tài liệu bồi dưỡng học sinh giỏi THPT – Môn Tin học Phần II: Chuyên đề nâng cao

CHUYÊN ĐỀ NÂNG CAO 6

CHUYÊN ĐỀ 6: QUY HOẠCH ĐỘNG

D BÀI TOÁN XÂU PALINDROME (XÂU ĐỐI XỨNG)

Palindrome hay còn gọi là xâu đối xứng, xâu đối gương là tên gọi của những xâu kí tự mà khi viết

từ phải qua trái hay từ trái qua phải thì xâu đó không thay đổi

VD: MADAM, IOI, Nhờ tính chất đặc biệt đó mà có khá nhiều bài tập có liên quan đến Palindrome, phần lớn trong chúng thường đi kèm với QHĐ

Bài 1: Xem một xâu có phải là Palindrome hay không?

Đây là một bài cơ bản, nhưng quan trọng vì nó được đề cập đến trong nhiều bài tập khác Cách làm tốt nhất là duyệt đơn thuần mất O(N)

Ý tưởng: Chương trình con kiểm tra đối xứng

IsPalin(S):boolean;

• n = length(s)

• Duyệt từ 1 đến n div 2: Nếu S[i]<>S[n-i+1] thì Exit(False);

• Exit(True);

Giải thích:

- Ta kiểm tra từ đầu đến ½ xâu S: Nếu gặp cặp kí tự nào khác nhau tức là xâu S ko đối xứng: Khi

đó ta kết thúc chương trình và cho kết quả là False

- Còn nếu sau khi duyệt mà ko dừng tức là đối xứng: kết thúc và cho kết quả True

Bài 2: Palindrome liên tiếp dài nhất

Cho một xâu S <= 1000 kí tự; tìm palindrome dài nhất là xâu con của S (Xâu con là một dãy các kí tự liên tiếp)

Cách 1: Duyệt trâu: ta sẽ kiểm tra từng đoạn con của xâu S

Ý tưởng: Ta sẽ dùng vòng lặp để tìm đoạn Palin dài nhất

- Smax = ‘’

- Kiểm tra tất cả các xâu con: Nếu xâu nào là palin thì so sánh mới smax và lưu lại.

Code:

For i:=1 to n-1 do

For j:=i+1 to n do nếu Ispalin(sij) và sij dài hơn Smax thì smax=sij

Độ phức tạp: 2 vòng for là O(n 2 ) thêm ispalin là O(n) vậy độ phức tạp là O(n 3 ).

Với cách 1 này: Khi s khoảng 1000 kí tự thì thời gian chạy chương trình sẽ rất lớn, không đáp ứng được yêu cầu

Cách 2: QHĐ

Dùng mảng L[i, j] có ý nghĩa: L[i, j] = true nếu đoạn gồm các kí tự từ i đến j của S là palindrome

Ta có công thức là:

L[i, i] = True

L[i, j] = L[i+1, j-1]; ( nếu s[i] = s[j] )

L[i, j] = False; ( nếu s[i] <> s[j] )

Đoạn chương trình như sau:

for i:=1 to n do L[i,i]:=true;

for j:=2 to n do

for i:=1 to j-1 do

if s[i]<>s[j] then L[i,j]:= false

else L[i,j]:=(i+1=j) or L[i+1,j-1];

Kết quả là : Max(j-i+1) <=j thỏa F[i,j] = True

• Độ phức tạp thuật toán là 0(N^2)

Thuật toán tốt hơn cho bài này: Các em có thể tìm đọc thêm thuật toán manacher.

Trang 2

Tài liệu bồi dưỡng học sinh giỏi THPT – Môn Tin học Phần II: Chuyên đề nâng cao Bài trên còn có một cách NlogN nữa là dùng Suffix Aray, thậm chí có cách O(N) là sử dụng Suffix Tree và thuật toán tìm LCA Đương nhiên cách cài đặt không hề dễ dàng

Bài 3: Chia Xâu thành các đoạn palindrome

Chia một xâu thành ít nhất các Palindrome (độ dài <=1000) Bài này phức tạp hơn bài trên, cách

làm thì vẫn là QHĐ

Gọi F[i] là số palindrome ít nhất mà đoạn 1 j chia thành được

Ta có công thức:

F[i] = max( F[j] + 1; "j < i thỏa mãn: đoạn j+1 i là palindrome)

Kết quả là F[n]

Đoạn chương trình như sau:

for i:=1 to n do f[i]:=n;

for i:=1 to n do

for j:=i-1 downto 0 do

if L[j+1,i] then F[i]:=min(f[i],f[j]+1);

Hai vòng for lồng nhau mất O(N^2)

Mảng L[i, j] có ý nghĩa tương tự bài 2

Bài 4: Pal - Ioicamp – Có bao nhiêu xâu con là Palindrome

Cho một xâu, hỏi nó có bao nhiêu xâu con là palindrome; xâu con ở đây gồm các kí tự không cần liên tiếp ( độ dài <= 120 )

Pal.iinp Pal.out

Đây là một bài tập rất thú vị Phương pháp là dùng QHĐ

Gọi F[i, j] là số palindrome là xâu con của đoạn i j

Ta có công thức :

• F[i, i] = 1;

• Nếu s[i] = s[j] thì f[i,j]=f[i+1,j]+f[i,j-1]+1

• Nếu s[i] <> s[j] thì f[i,j]=f[i+1,j]+f[i,j-1]-f[i+1,j-1];

Đoạn chương trình như sau :

//QHD: f[i,j] la so luong palindrome trong doan i j

for i:=1 to n do f[i,i]:=1;

for j:=2 to n do

for i:=j-1 downto 1 do

if s[i]=s[j] then f[i,j]:=f[i+1,j]+f[i,j-1]+1

else f[i,j]:=f[i,j-1]+f[i+1,j]-f[i+1,j-1];

write(f[1,n]);

Độ phức tạp của thuật toán là O(N2) Vì vậy, chúng ta hoàn toàn có thể làm với N = 1000

Bài 5: Thêm vào ít kí tự nhất để thành xâu Palindrome

Cho một xâu, hỏi phải thêm vào nó ít nhất bao nhiêu xâu kí tự để nó trở thành một palindrome (độ dài

<= 500)

Bài này cũng sử dụng QHĐ:

Gọi F[i, j] là số phép biến đổi ít nhất cần thêm vào đoạn i j để đoạn i j trở thành palindrome

Ta có công thức :

- F[i, i] = 0;

- Nếu s[i] = s[j] thì F[i, j] = F[i+1, j-1]

- Nếu s[i] <> s[j] thì F[i, j] = Min( F[i, j-1], F[i+1, j] ) + 1; Đoạn chương trình:

for i:=1 to n do f[i,i]:=0;

Trang 3

Tài liệu bồi dưỡng học sinh giỏi THPT – Môn Tin học Phần II: Chuyên đề nâng cao for j:=2 to n do

for i:=j-1 downto 1 do

if s[i]<>s[j] then f[i,j]:=min(f[i,j-1],f[i+1,j])+1

else f[i,j]:=f[i+1,j-1];

write(f[1,n]);

Bài 6: The next palindrome - SPOJ

Cho nhiều số <= 106, với mỗi số, tìm số bé nhất có dạng palindrome lớn hơn số đã cho

Ví Dụ :

NextPalin.inp NextPalin.out 2

808 2133

818 2222 [i]Gợi ý: dùng phương pháp đếm kết hợp QHĐ

Ngày đăng: 15/02/2016, 10:16

TỪ KHÓA LIÊN QUAN

w