1. Trang chủ
  2. » Luận Văn - Báo Cáo

Phương pháp quy hoạch động và vận dụng kết hợp giải các bài toán chuyên tin bậc thpt

86 12 0

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

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Định dạng
Số trang 86
Dung lượng 1,11 MB

Các công cụ chuyển đổi và chỉnh sửa cho tài liệu này

Nội dung

Quy hoạch động là một chuyên đề rất hay và mạnh của tin học đã vậy thực hiện quy hoạch động trên dãy bit lại còn cho kết quả khả quan hơn nữa Như chúng ta đã biết phép xử lí bit có thời gian thực hiện rất nhỏ nhỏ hơn phép số học toán thông thường Vì vậy trong luận văn này phạm vi dữ liệu mà tôi muốn đề cập đến là bit và quy hoạch động trên dãy bit Bên cạnh đó luận văn cũng trình bày một số cách quy hoạch trên dãy đã được sắp xếp cùng với một số bài toán điển hình dùng để minh họa cho quy hoạch động Các bài toán được phân tích thiết kế và cài đặt theo phương pháp quy hoạch động và phương pháp khác nhằm để so sánh và thấy được ưu điểm của phương pháp quy hoạch động chủ yếu là về mặt thời gian chạy của thuật toán Luận văn cũng đã cho thấy có sự cùng dạng của một lớp các bài toán có thể chuyển về xử lý bằng cách mô tả các trạng thái của bài toán bằng dãy bit và từ đó thực hiện quy hoạch động trên dãy bit đó để đạt được kết quả tối ưu

Trang 1

TRƯỜNG ĐẠI HỌC BÁCH KHOA

THÁI PHONG NGHĨA

PHƯƠNG PHÁP QUY HOẠCH ĐỘNG VÀ VẬN DỤNG

KẾT HỢP GIẢI CÁC BÀI TOÁN CHUYÊN TIN BẬC THPT

LUẬN VĂN THẠC SĨ KHOA HỌC CHUYÊN NGÀNH KHOA HỌC MÁY TÍNH

Trang 2

TRƯỜNG ĐẠI HỌC BÁCH KHOA

-

THÁI PHONG NGHĨA

KẾT HỢP GIẢI CÁC BÀI TOÁN CHUYÊN TIN BẬC THPT

Chuyên ngành : Khoa học máy tính

Trang 3

LỜI CAM ĐOAN

Tôi cam đoan đây là công trình nghiên cứu của riêng tôi.Các số liệu, kết quả nêu trong luận văn là trung thực và chưa từng được ai công bố trong bất kỳ công trình nào khác

Tác giả

Thái Phong Nghĩa

Trang 4

MỤC LỤC

Trang

MỞ ĐẦU 1

1 Lý do chọn đề tài 1

2 Mục tiêu nghiên cứu 2

3 Đối tượng và phạm vi nghiên cứu 2

4 Phương pháp nghiên cứu 2

5 Ý nghĩa khoa học và thực tiễn của đề tài 2

CHƯƠNG 1: LÝ THUYẾT VỀ QUY HOẠCH ĐỘNG 3

1.1 Giới thiệu về phương pháp quy hoạch động 3

1.1.1 Bài toán tối ưu 3

1.1.2 Nguyên lý Bellman 4

1.1.3 Bảng phương án 4

1.2 Nhận dạng bài toán quy hoạch động 5

1.3 Ưu điểm của quy hoạch động 5

1.4 Các bước thực hiện quy hoạch động 6

1.4.1 Xây dựng công thức truy hồi 6

1.4.2 Tổ chức dữ liệu và chương trình 7

1.4.3 Làm tốt (tối ưu thuật toán nếu được): 7

1.4.4 Truy vết tìm phương án tối ưu 7

1.5 Các lớp bài toán quy hoạch động và ứng dụng 8

1.5.1 Dạng 1: Dãy con đơn điệu dài nhất 8

1.5.1.1 Mô hình 8

1.5.1.2 Công thức QHĐ 8

1.5.1.3 Cài đặt 8

1.5.1.4 Một số bài toán là biến thể cùng lớp của “dãy con đơn điệu dài nhất” 9

1.5.2 Dạng 2: Chia kẹo 10

1.5.2 1 Mô hình 10

1.5.2 2 Công thức 10

1.5.2 3 Cài đặt 10

1.5.2 4 Một số bài toán biến thể cùng lớp với bài toán “chia kẹo” 11

1.5.3 Dạng 3: Xâu con chung dài nhất 12

1.5.3 1 Mô hình 12

1.5.3 2 Công thức QHĐ 12

1.5.3 3 Cài đặt 12

1.5.3 4 Một số bài toán là biến thể cùng lớp của “Xâu con chung dài nhất” 13

1.5.4 Một số dạng khác: 14

1.6 Hạn chế của quy hoạch động 14

CHƯƠNG 2: GIỚI THIỆU MỘT SỐ THUẬT TOÁN VÀ CẤU TRÚC DỮ LIỆU ĐỂ KẾT HỢP VỚI PHƯƠNG PHÁP QUY HOẠCH ĐỘNG 15

2.1 Bài toán 1: Phần thưởng 15

2.2 Bài toán 2: Đoạn con liên tiếp có tổng lớn nhất 17

Trang 5

2.3 Quy hoạch động dựa trên bài toán đã được sắp xếp 19

2.3.1 Sắp xếp 19

2.3.2 Phát biểu bài toán 20

2.3.3 Các thuật toán sắp xếp thông dụng 20

2.3.3.1 Thuật toán sắp xếp nổi bọt (Bubble Sort) 20

2.3.3.2 Thuật toán sắp xếp nhanh (Quick Sort) 22

2.3.3.4 Sắp xếp bằng đếm phân phối (Distribution Counting) 24

2.3.3.5 Một số bài toán 24

2.4 Quy hoạch động kết hợp xử lý Bit để mô tả trạng thái bài toán 29

2.4.1 Bit và các thao tác xử lý Bit 29

2.4.1.1 Quy ước về vị trí của các bit 29

2.4.1.2 Các phép toán logic 29

2.4.1.3 Một số ứng dụng 31

2.4.2 Một số bài toán cùng lớp có thể dùng quy hoạch động kết hợp bit 33

CHƯƠNG 3: CÀI ĐẶT CHƯƠNG TRÌNH MINH HỌA BẰNG FREE PASCAL 45

3.1 Bài toán : Robot 45

3.2 Bài toán : Đoạn con gối nhau dài nhất 45

3.3 Bài toán : Chọn ô 46

3.4 Bài toán : Sherry 48

KẾT LUẬN VÀ KIẾN NGHỊ 51

1 Kết quả đạt được 51

2 Kiến nghị và hướng phát triển 52

DANH MỤC TÀI LIỆU THAM KHẢO 53 PHỤ LỤC

1 Code bài: “Phần thưởng”

2 Code bài: “Đoạn con liên tiếp có tổng lớn nhất”

3 Code bài: “Robot”

4 Code bài: “Đoạn gối nhau dài nhất”

5 Code bài: “Chọn ô”

6 Code bài: “Sherry”

Trang 6

PHƯƠNG PHÁP QUY HOẠCH ĐỘNG VÀ VẬN DỤNG KẾT HỢP

GIẢI CÁC BÀI TOÁN CHUYÊN TIN BẬC THPT

Học viên: Thái Phong Nghĩa Chuyên ngành: Khoa học máy tính

Mã số: 60.48.01 Trường Đại học Bách khoa

Tóm tắt - Quy hoạch động là một chuyên đề rất hay và mạnh của tin học, đã vậy thực hiện

quy hoạch động trên dãy bit lại còn cho kết quả khả quan hơn nữa Như chúng ta đã biết, phép

xử lí bit có thời gian thực hiện rất nhỏ, nhỏ hơn phép số học toán thông thường Vì vậy, trong luận văn này, phạm vi dữ liệu mà tôi muốn đề cập đến là bit và quy hoạch động trên dãy bit Bên cạnh đó luận văn cũng trình bày một số cách quy hoạch trên dãy đã được sắp xếp cùng với một số bài toán điển hình dùng để minh họa cho quy hoạch động Các bài toán được phân tích, thiết kế và cài đặt theo phương pháp quy hoạch động và phương pháp khác nhằm để so sánh và thấy được ưu điểm của phương pháp quy hoạch động (chủ yếu là về mặt thời gian chạy của thuật toán) Luận văn cũng đã cho thấy có sự cùng dạng của một lớp các bài toán có thể chuyển về xử lý bằng cách mô tả các trạng thái của bài toán bằng dãy bit và từ đó thực hiện quy hoạch động trên dãy bit đó để đạt được kết quả tối ưu

Từ khóa – Quy hoạch động; sắp xếp; xử lý bit; trạng thái của bài toán; Bài toán tối ưu

DYNAMIC PROGRAMMING METHOD AND COMBINATION OF OTHERS TO SOLVE ADVANCED PROBLEMS IN INFORMATICS AT HIGH SCHOOL LEVEL

Abstract – Dynamic programming is a great and powerful subject of informatics, so implementing dynamic programming on the series of bit is more important As we all know, bit processing has a very small execution time, which is smaller than regular arithmetic operations The dissertation, therefore, aims to delve into bit and dynamic programming on the series of bit In addition, the thesis also presents some of the planning methods on the designed series of bit along with some typical problems used to illustrate the dynamic programming The problems are analyzed, designed and implemented by dynamic programming and other methods to compare and find the advantages of the dynamic programming (mainly in terms of execution time of algorithms) The thesis also shows the similarity of a class of mathematical problems that can be transferred to the process by describing the states of the problem by the series of bit and from which dynamic programming on that series of bit is to achieve optimal results

Keywords – Dynamic programming; sort; bit processing; the state of the problem; optimal

problem

Trang 7

DANH MỤC CÁC KÝ HIỆU, CHỮ VIẾT TẮT

Các ký hiệu

O() Độ phức tạp thuật toán

A[i,j] Mảng 2 chiều có tên là A, chứa giá trị tại dòng i, cột j

B[i] Mảng 1 chiều có tên B, chứa giá trị tại cột i

Abs() Hàm cho giá trị tuyệt đối trong Pascal

Các chữ viết tắt

THPT Trung học phổ thông Trường cấp 3 trong hệ giáo dục

phổ thông

Bubble sort Sắp xếp nổi bọt Tên thuật toán

Quick Sort Sắp xếp nhanh Tên thuật toán

Distribution

Test Bộ dữ liệu kiểm thử Dùng kiểm tra tính đúng đắn

của chương trình

Thông thường là file tệp văn bản chứa dữ liệu để chương trình lấy dữ liệu từ đây vào xử

Thông thường là file tệp văn bản chứa dữ liệu đã được chương trình xuất kết quả ra theo yêu cầu của đề bài

Trang 8

DANH MỤC CÁC BẢNG

2.1 Bảng minh họa kết quả bài toán “Phần thưởng” 15

2.2 Bảng lưu giá trị của F[i,j] bài toán “Phần

2.3 Tìm giá trị hình vuông lớn nhất bài toán “Phần

2.4 Bảng phương án tính F[n,x] của bài “Chọn ô” 36

2.7 Các bảng Fx, vet, V thể hiện quá trình truy vết

Trang 9

DANH MỤC CÁC HÌNH

2.6 Đồ thị biểu diễn đường đi giữa các thành phố bài toán

3.1 Kết quả chạy chương trình với m = 6 và n=5, bài “Robot”. 45

3.2 Kết quả chạy chương trình với n=5, bài “Đoạn con gối nhau

Trang 10

MỞ ĐẦU

1 Lý do chọn đề tài

Hiện nay nhiệm vụ phát hiện, đào tạo và bồi dưỡng học sinh giỏi là một nhiệm

vụ trọng tâm của các trường THPT Chuyên của tất cả các tỉnh thành trong cả nước, nhằm mục đích phát hiện bồi dưỡng và đào tạo nhân tài, tạo ra một đội ngũ học sinh chất lượng cao làm tiền đề để phát triển nâng cao hơn nữa ở bậc đại học, sau đại học cho các em học sinh Môn Tin học tự hào cũng là một môn học quan trọng không kém nên được đưa vào chương trình thi học sinh giỏi các cấp hằng năm như: thi học sinh giỏi cấp Tỉnh (thành phố), thi học sinh giỏi Olympic 30/04 (từ Đà Nẵng trở vào phía Nam), thi học sinh giỏi Quốc gia, bên cạnh đó còn có thi Tin học trẻ không chuyên (cấp Tỉnh và Toàn quốc)

Cùng với nhiệm vụ quan trọng của cả nước là đào tạo và bồi dưỡng nhân tài nói chung trong các lĩnh vực khoa học tự nhiên và khoa học xã hội, môn tin học nói riêng vẫn được sự quan tâm của Bộ giáo dục và đào tạo, Sở giáo dục và đào tạo các tỉnh thành trong cả nước, nên luôn có các kỳ thi học sinh giỏi môn tin học cho các em học sinh, bên cạnh đó còn có các cuộc thi cho sinh viên ở bậc đại học như: Olympic Tin học sinh viên, Mùa hè sáng tạo, Nhân tài đất Việt, và các cuộc thi quốc tế: ACM ICPC (International Collegiate Programming Contest), Google Summer of code, Top Coder,

Trong vai trò là một giáo viên Tin học giảng dạy tại trường THPT Chuyên Nguyễn Thiện Thành – TP Trà Vinh, hàng năm đều phải tham gia vào công tác bồi dưỡng học sinh giỏi của bộ môn, cho đến nay qua nhiều năm bồi dưỡng, bản thân tôi nhận thấy, trong cấu trúc của các đề thi học sinh giỏi môn Tin học, số lượng các bài toán trong một đề thi có thể giải bằng phương pháp quy hoạch động thường chiếm từ

30 – 70% của một đề thi, bởi khi ra đề thi ban tổ chức thường rãi đều các chuyên mục của các phương pháp như: duyệt, qui hoạch động và các thuật toán ứng dụng mô hình

đồ thị, tuy nhiên trong đó có một số bài toán duyệt và ứng dụng mô hình đồ thị vẫn

có thể áp dụng phương pháp quy hoạch động để giải Vì vậy có thể nói, quy hoạch động là một chuyên đề rất quan trọng mà mỗi học sinh thi tham gia đội tuyển học sinh giỏi đều phải nắm được nếu muốn đạt các thứ hạng cao ở các kỳ thi

Với những lý do thiết thực đó, tôi xin chọn thực hiện đề tài: “PHƯƠNG PHÁP

QUY HOẠCH ĐỘNG VÀ VẬN DỤNG KẾT HỢP GIẢI CÁC BÀI TOÁN CHUYÊN

TIN BẬC THPT”

Trang 11

2 Mục tiêu nghiên cứu

Xây dựng và phân tích có hệ thống các bài tập có thể giải bằng phương pháp Quy hoạch động, phân lớp chúng thành các lớp bài toán bằng cách nhận diện dựa trên kinh nghiệm của người học từ các bài toán quy hoạch động điển hình, kinh điển Vận dụng kết hợp để giải các bài toán chuyên Tin trong công tác bồi dưỡng học sinh giỏi môn Tin học Giúp cho học sinh đạt kết quả cao hơn trong các kỳ thi, có thể dùng làm tài liệu tham khảo để hỗ trợ cho học sinh giáo viên tin học dạy bồi dưỡng chuyên tin, và trên hết giúp củng cố lại kiến thức về phương pháp quy hoạch động cho bản thân

3 Đối tượng và phạm vi nghiên cứu

 Phương pháp quy hoạch động

 Các bài toán tối ưu có thể giải bằng phương pháp quy hoạch động

 Các đề thi học sinh giỏi tin học các cấp

4 Phương pháp nghiên cứu

 Nghiên cứu lý thuyết về phương pháp quy hoạch động, nhận dạng các bài toán có thể giải bằng phương pháp quy hoạch động và phân tích các ưu điểm của nó từ đó kết hợp thêm các phương pháp khác để áp dụng giải các bài toán tối ưu

 Thiết kế thuật toán dựa trên phương pháp quy hoạch động

 Dùng Free Pascal để cài đặt chương trình, chạy thử nghiệm trên một số bộ

dữ liệu kiểm thử, đánh giá kết quả

 Áp dụng bồi dưỡng học sinh giỏi

5 Ý nghĩa khoa học và thực tiễn của đề tài

Ý nghĩa khoa học:

 Nghiên cứu và phân tích phương pháp quy hoạch động

 Vận dụng kết hợp vào việc giải các bài toán chuyên tin

Trang 12

CHƯƠNG 1 - LÝ THUYẾT VỀ QUY HOẠCH ĐỘNG 1.1 Giới thiệu về phương pháp quy hoạch động

Trong ngành khoa học máy tính, phương pháp quy hoạch động là một phương pháp làm giảm thời gian chạy của các thuật toán thể hiện các tính chất của các bài toán con phụ thuộc nhau và cấu trúc con tối ưu [14]

Phương pháp quy hoạch động cùng nguyên lý tối ưu được nhà toán học Mỹ R.Bellman đề xuất vào những năm 50 của thế kỷ 20 Phương pháp này đã được áp dụng để giải hàng loạt bài toán thực tế trong các quá trình kỹ thuật công nghệ, tổ chức sản xuất, kế hoạch hoá kinh tế… Tuy nhiên cần lưu ý rằng có một số bài toán mà cách giải bằng quy hoạch động tỏ ra không thích hợp

Quy hoạch động là kỹ thuật thiết kế bottom-up (từ dưới lên) Nó được bắt đầu với những trường hợp con nhỏ nhất (thường là đơn giản nhất và giải được ngay) Bằng

cách tổ hợp các kết quả đã có (không phải tính lại) của các trường hợp con, sẽ đạt tới

kết quả của trường hợp có kích thước lớn dần lên và tổng quát hơn, thông qua công thức truy hồi, cho đến khi cuối cùng đạt tới lời giải của trường hợp tổng quát nhất, đó cũng là giá trị tối ưu cần tìm

1.1.1 Bài toán tối ưu

Trong thực tế, ta thường gặp một số loại bài toán tối ưu sau [2]: Có một đại

lượng f hình thành trong một quá trình gồm nhiều giai đoạn và ta chỉ quan tâm đến kết

quả cuối cùng là giá trị của f phải lớn nhất hoặc nhỏ nhất, ta gọi chung là giá trị tối

ưu của f Giá trị của f phụ thuộc vào những đại lượng xuất hiện trong bài toán mà mỗi

bộ giá trị của chúng được gọi là một trạng thái của hệ thống và phụ thuộc vào cách thức đạt được giá trị f trong từng giai đoạn mà mỗi cách tổ chức được gọi là một điều khiển Đại lượng f thường được gọi là hàm mục tiêu và quá trình đạt được giá trị tối

ưu của f được gọi là quá trình điều khiển tối ưu

Hình 1.1 Các tiêu chí của bài toán tối ưu thường là chi phí hoặc giá trị

Trang 13

1.1.2 Nguyên lý Bellman

Bellman phát biểu nguyên lý tối ưu (cũng gọi là nguyên lý Bellman) mà ý tưởng

cơ bản là như sau: “Với mỗi quá trình điều khiển tối ưu, đối với trạng thái bắt đầu A 0,

với trạng thái A trong quá trình đó, phần quá trình kể từ trạng thái A xem như trạng

thái bắt đầu cũng là tối ưu”

Chú ý rằng nguyên lý này được thừa nhận mà không chứng minh

Phương pháp tìm điều khiển tối ưu theo nguyên lý Bellman thường được gọi là

quy hoạch động Thuật ngữ này nói lên thực chất của quá trình điều khiển là động: có

thể trong một số bước đầu tiên lựa chọn điều khiển tối ưu dường như không tốt nhưng tựu chung cả quá trình lại là tốt nhất

Ta có thể giải thích ý này qua bài toán sau: Cho một dãy N số nguyên A 1,

A 2 ,…,A N Hãy tìm cách xoá đi một số ít nhất số hạng để dãy còn lại là đơn điệu hay nói cách khác hãy chọn một số nhiều nhất các số hạng sao cho dãy B gồm các số hạng đó

theo trình tự xuất hiện trong dãy A là đơn điệu

Quá trình chọn B được điều khiển qua N giai đoạn để đạt được mục tiêu là số lượng số hạng của dãy B là nhiều nhất, điều khiển ở giai đoạn i thể hiện việc chọn hay không chọn A i vào dãy B

Giả sử dãy đã cho là 1 8 10 2 4 6 7 Nếu ta chọn lần lượt 1, 8, 10 thì chỉ chọn được 3 số hạng nhưng nếu bỏ qua 8 và 10 thì ta chọn được 5 số hạng 1, 2, 4, 6, 7

Khi giải một bài toán bằng cách “chia để trị” chuyển việc giải bài toán kích thước lớn về việc giải nhiều bài toán cùng kiểu có kích thước nhỏ hơn thì thuật toán này thường được thể hiện bằng các chương trình con đệ quy Khi đó, trên thực tế, nhiều kết quả trung gian phải tính lặp đi lặp lại nhiều lần

1.1.3 Bảng phương án

Ý tưởng cơ bản của quy hoạch động thật đơn giản: tránh tính toán lại mọi thứ hai lần, mà lưu giữ kết quả đã tìm kiếm được vào một bảng - gọi là bảng phương án, làm giả thiết cho việc tìm kiếm những kết quả của trường hợp sau Chúng ta sẽ làm đầy dần giá trị của bảng này bởi các kết quả của những trường hợp trước đã được giải Kết quả cuối cùng chính là kết quả của bài toán cần giải Nói cách khác phương pháp quy hoạch động đã thể hiện sức mạnh của nguyên lý chia để trị đến cao độ Đồng thời

nó cũng khắc phục được việc tính toán lặp lại của đệ quy

Trong một số trường hợp, khi giải một bài toán A, trước hết ta tìm họ bài toán A(p) phụ thuộc tham số p (có thể p là một véc tơ) mà A(p0)=A với p0 là trạng thái ban

đầu của bài toán A Sau đó tìm cách giải họ bài toán A(p) với tham số p bằng cách áp

Trang 14

dụng nguyên lý tối ưu của Bellman Cuối cùng cho p=p0 sẽ nhận được kết quả của bài

toán A ban đầu

1.2 Nhận dạng bài toán quy hoạch động

Quy hoạch động là một phương pháp hữu hiệu để giải quyết một bài toán tối

ưu Có một vài yếu tố mà người lập trình cần chú ý khi nhận diện bài toán có thể giải bằng phương phương pháp quy hoạch động hay không đó là:

- Thuộc dạng bài toán tối ưu

- Có dạng tương tự với các lớp bài toán về quy hoạch động điển hình, cơ bản

- Gặp bài toán có tính chất truy hồi

- Lời giải bài toán ở bước sau được xây dựng thông qua lời giải bài toán ở bước trước

- Tìm được công thức truy hồi để phối hợp các bài toán con thành bài toán lớn hơn

- Kích thước bài toán không quá lớn

Nhưng để phát hiện ra và cài đặt tốt một bài quy hoạch động là rất khó khăn Thường thì chúng ta hay tiếp cận với những bài toán quy hoạch động mà đọc lên đã

có ngay dạng hay phương pháp giải, nhưng như vậy là chưa đủ bởi lẽ quy hoạch động không dừng lại ở đó Chúng ta chỉ có thể giác ngộ tư tưởng để giải một bài quy hoạch động chứ chúng ta không thể học hết được toàn bộ mọi phương pháp quy hoạch Vì vậy cách tốt nhất để giải được một bài toán quy hoạch động đòi hỏi tư duy tốt trong lập trình, và quan trọng là phải có kinh nghiệm, mà kinh nghiệm thì cần phải tích lũy bằng cách giải thật nhiều bài toán về quy hoạch động với nhiều dạng khác nhau

1.3 Ưu điểm của quy hoạch động

Có nhiều phương pháp để giải một bài toán tối ưu Có thể kể đến như: tham lam (Greedy), nhánh cận (Branch and Bound), vét cạn, … Tuy nhiên đa số các phương pháp đó thường ít có hiệu quả do thường cài đặt dưới dạng thủ tục đệ qui (nhánh cận), hoặc cho lời giải gần đúng chứ không phải tối ưu (tham lam), hoặc có thể tìm được lời giải tối ưu nhưng lại quá lâu (vét cạn)

Về bản chất, đệ qui và quy hoạch động là tương tự nhau, tức là đều cùng giải các bài toán con để kết hợp tìm ra nghiệm của bài toán sau cùng Nhưng trong khi đệ qui thực hiện việc giải bài toán con lặp đi lặp lại nhiều lần gây lãng phí tài nguyên và thời gian thì quy hoạch động khắc phục được điều đó bằng cách mỗi bài toán con chỉ giải 1 lần và lưu trữ chúng lại để sử dụng cho những bài toán lớn hơn

Trong khi phương pháp nhánh cận chỉ là một bước cải tiến của cách cài đặt đệ qui quay lui, phương pháp này sẽ gặp khó trong trường hợp đặt cận không đủ tốt để có

Trang 15

thể loại bỏ bớt các trường hợp không cần xét Suy cho cùng nhánh cận có tốt hơn nhưng không đáng kể

Phương pháp vét cạn thì lại có nhược điểm riêng, mặc dù trên lý thuyết thì có thể cho được phương án tối ưu Nhưng thực tế vét cạn là xét tất cả mọi khả năng có thể

có của nghiệm, từ đó chọn ra nghiệm tối ưu Do đó vét cạn chỉ khả thi trong trường hợp bài toán có kích thước dữ liệu nhỏ

Vì vậy có thể nói quy hoạch động giải quyết được hầu như tất cả các nhược điểm của các phương pháp trên

1.4 Các bước thực hiện quy hoạch động

1.4.1 Xây dựng công thức truy hồi

Dựa vào nguyên lý tối ưu tìm cách chia quá trình giải bài toán thành từng giai đoạn, sau đó tìm hệ thức biểu diễn tương quan quyết định của bước đang xử lý với các bước đã xử lý trước đó Hoặc tìm cách phân rã bài toán thành các “bài toán con” tương

tự có kích thước nhỏ hơn, tìm hệ thức nêu quan hệ giữa kết quả bài toán kích thước đã cho với kết quả của các “bài toán con” cùng kiểu có kích thước nhỏ hơn của nó nhằm xây dựng công thức truy hồi

Về một cách xây dựng công thức truy hồi:

Giả sử bài toán mà ta cần tìm là chi phí tối ưu dạng Max Gọi Fi là giá trị lớn nhất khi xét đến phần tử thứ i

Tùy theo bài toán, ta có thể nhận ra các bài toán cơ sở của nó một cách rõ ràng

và hiển nhiên Thông thường các giá trị này là F0 hoặc F1 hoặc F2 … Khởi tạo bằng cách gán các giá trị ban đầu cho chúng

Từ các giá trị ban đầu nêu trên, ta tăng dần số lượng các phần tử lên (tăng độ lớn của bài toán), tìm điểm chung trong cách tính các phần tử từ bài toán cơ sở (F0

hoặc F1) đến bài toán đang xét (Fi) Từ đó ta có được công thức truy hồi

Thông thường công thức truy hồi có dạng:

F i = Max(F i-1 , F i) {với i = 1 n} (*)

Trong đó

- Fi là giá trị lớn nhất khi xét đến phần tử thứ i

- Max là hàm lấy giá trị lớn nhất của 1 trong các đối số của nó

- Fi-1 là bài toán con đã tối ưu ở bước liền kề trước đó

- Fi-1 cũng được tính theo công thức Fi-1 = Max(Fi-2, Fi-1)

- Và Fi-2 = Max(Fi-3, Fi-2)

- … cho đến

Trang 16

- F1

- F0

1.4.2 Tổ chức dữ liệu và chương trình

Tổ chức dữ liệu sao cho đạt các yêu cầu sau:

 Dữ liệu được tính toán dần theo các bước

 Dữ liệu được lưu trữ để giảm lượng tính toán lặp lại

 Kích thước miền nhớ dành cho lưu trữ dữ liệu càng nhỏ càng tốt, kiểu dữ liệu được chọn phù hợp, nên chọn đơn giản dễ truy cập

1.4.3 Làm tốt (tối ưu thuật toán nếu được)

Làm tốt thuật toán bằng cách thu gọn hệ thức (*) và giảm kích thước miền nhớ Thường tìm cách dùng mảng một chiều thay cho mảng hai chiều nếu giá trị một dòng (hoặc cột) của mảng hai chiều chỉ phụ thuộc một dòng (hoặc cột) kề trước

Trong một số trường hợp có thể thay mảng hai chiều với các giá trị phần tử chỉ nhận giá trị 0, 1 bởi mảng hai chiều mới bằng cách dùng kỹ thuật xử lý bit

1.4.4 Truy vết tìm phương án tối ưu

Thông thường kết quả tối ưu của một bài toán quy hoạch động là sau khi đã giải được bài toán sau cùng (bài toán thứ n, hay Fn), nếu bảng phương án là mảng 2 chiều thì hoặc là giá trị tối ưu (GTTU) nằm ở cột cuối hoặc là GTTU nằm ở dòng cuối Từ các vị trí chứa các GTTU đó, ta tiến hành truy vết ngược trở về đi qua các bài toán con trước nó cũng đã đạt được GTTU, cho đến khi trở về bài toán cơ sở ban đầu thì dừng

Vậy để có thể truy vết được thì ta phải tiến hành đánh dấu tại GTTU của bài toán thứ i mà ta đạt được Cụ thể, khi tiến hành cài đặt công thức (*) ở trên, ta phải lưu vết:

Trang 17

If Fi-1 > Fi Then

Begin

Fi := Fi-1Lưu vết {chọn Fi-1} End Else

Lưu vết {không chọn Fi-1}

1.5 Các lớp bài toán quy hoạch động và ứng dụng

Chúng ta đều biết rằng điều khó nhất để giải một bài toán quy hoạch động (QHĐ) là biết rằng nó là một bài toán QHĐ và tìm được công thức QHĐ của nó Rất khó nếu ta mò mẫm từ đầu, nhưng nếu chúng ta đưa được bài toán cần giải về một bài toán QHĐ kinh điển thì sẽ dễ dàng hơn nhiều Do đó, tìm hiểu mô hình, công thức và cách cài đặt những bài toán QHĐ kinh điển là một việc rất cần thiết Trong phần này, tôi xin giới thiệu một số bài toán QHĐ kinh điển và những biến thể của chúng Phần này chủ yếu tập trung vào giới thiệu mô hình, công thức và một số gợi ý trong cài đặt chứ không đi chi tiết vào việc phát biểu bài toán, mô tả input/output, chứng minh công thức hay viết chương trình cụ thể [7]

1.5.1 Dạng 1: Dãy con đơn điệu dài nhất

Trang 18

Như vậy chi phí không gian của bài toán là O(n), chi phí thời gian là O(n2

)

1.5.1.4 Một số bài toán là biến thể cùng lớp của “dãy con đơn điệu dài nhất”

Bài toán dãy con đơn điệu dài nhất có biến thể đơn giản nhất là bài toán dãy con đơn điệu giảm dài nhất, tuy nhiên chúng ta có thể coi chúng như là một Sau đây là một số bài toán khác

a) Bài toán: Bố trí phòng họp

Có n cuộc họp, cuộc họp thứ i bắt đầu vào thời điểm ai và kết thúc ở thời điểm

bi Do chỉ có một phòng hội thảo nên 2 cuộc họp bất kì sẽ được cùng bố trí phục vụ nếu khoảng thời gian làm việc của chúng chỉ giao nhau tại đầu mút Hãy bố trí phòng họp để phục vụ được nhiều cuộc họp nhất

Ý tưởng thuật toán:

Sắp xếp các cuộc họp tăng dần theo thời điểm kết thúc (bi) Thế thì cuộc họp i

sẽ bố trí được sau cuộc họp j nếu và chỉ nếu j < i và bj ≤ ai Yêu cầu bố trí được nhiều cuộc họp nhất có thể đưa về việc tìm dãy các cuộc họp dài nhất thoả mãn điều kiện trên

b) Bài toán: Cho thuê máy

Trung tâm tính toán hiệu năng cao nhận được đơn đặt hàng của n khách hàng Khách hàng i muốn sử dụng máy trong khoảng thời gian từ ai đến bi và trả tiền thuê là

ci Hãy bố trí lịch thuê máy để tổng số tiền thu được là lớn nhất mà thời gian sử dụng máy của 2 khách hàng bất kì được phục vụ đều không giao nhau (cả trung tâm chỉ có một máy cho thuê)

Ý tưởng thuật toán:

Tương tự như bài toán a), nếu sắp xếp các đơn đặt hàng theo thời điểm kết thúc,

ta sẽ đưa được bài toán b) về bài toán tìm dãy con có tổng lớn nhất Bài toán này là biến thể của bài toán tìm dãy con tăng dài nhất, ta có thể cài đặt bằng đoạn chương trình như sau:

for i:=1 to n do begin

L[i]:=c[i];

for j:=1 to i -1 do

if (b[j]<=a[i]) and (L[i] <L[j] + c[i]) then L[i]:=L[j]+c[i];

end;

c) Bài toán: Dãy tam giác bao nhau

Cho n tam giác trên mặt phẳng Tam giác i bao tam giác j nếu 3 đỉnh của tam giác j đều nằm trong tam giác i (có thể nằm trên cạnh) Hãy tìm dãy tam giác bao nhau

có nhiều tam giác nhất

Ý tưởng thuật toán:

Trang 19

Sắp xếp các tam giác tăng dần về diện tích Khi đó tam giác i sẽ bao tam giác j nếu j < i và 3 đỉnh của j nằm trong i Từ đó có thể đưa về bài toán tìm dãy tăng dài nhất

Việc kiểm tra điểm M có nằm trong tam giác ABC không có thể dựa trên phương pháp tính diện tích: điểm M nằm trong nếu S(ABC) = S(ABM) + S(ACM) + S(BCM)

Bài toán có một số biến thể khác như tìm dãy hình tam giác, hình chữ nhật bao nhau có tổng diện tích lớn nhất

d) Bài toán: Dãy đổi dấu

Cho dãy a1, a2, an Hãy dãy con đổi dấu dài nhất của dãy đó Dãy con con đổi dấu ai1,ai2, aik phải thoả mãn các điều kiện sau:

ai1 <Ai2 > ai3 < hoặc i1 > ai2 < a i3 > các chỉ số phải cách nhau ít nhất L: i2 - i1 ≥ L, i3-i2 ≥ L chênh lệch giữa 2 phần tử liên tiếp nhỏ hơn U: |ai1 - ai2| ≤ U, |ai2 - ai3| ≤ U

Ý tưởng thuật toán:

Gọi L(i) là số phần tử của dãy con đổi dấu có phần tử cuối cùng là ai và phần tử cuối cùng lớn hơn phần tử đứng trước Tương tự, P(i) là số phần tử của dãy con đổi dấu có phần tử cuối cùng là ai và phần tử cuối cùng nhỏ hơn phần tử đứng trước Ta dễ dàng suy ra:

Đặt L(i,t)=1 nếu có thể tạo ra tổng t từ một dãy con của dãy gồm các phần tử

a 1 ,a 2 , a i Ngược lại thì L(i,t)=0 Nếu L(n,S)=1 thì đáp án của bài toán trên là 'có' Ta

có thể tính L(i,t) theo công thức: L(i,t) = 1 nếu L(i - 1,t)=1 hoặc L(i-1,t - a[i])=1

1.5.2 3 Cài đặt

Nếu áp dụng luôn công thức trên thì ta cần dùng bảng phương án hai chiều Ta

có thể nhận xét rằng để tính dòng thứ i, ta chỉ cần dòng i -1 Bảng phương án khi đó chỉ cần 1 mảng 1 chiều L[0 S] và được tính như sau:

L[t]:=0; L[0]:=1;

for i := 1 to n do

for t := S downto a[i] do

if (L[t]=0) and (L[t - a[i]]=1) then L[t]:=1;

Dễ thấy chi phí không gian của cách cài đặt trên là O(m), chi phí thời gian là O(nm), với m là tổng của n số

Trang 20

1.5.2 4 Một số bài toán biến thể cùng lớp với bài toán “chia kẹo”

a) Bài toán: Chia kẹo

Cho n gói kẹo, gói thứ i có ai viên Hãy chia các gói thành 2 phần sao cho chênh lệch giữa 2 phần là ít nhất

Ý tưởng thuật toán:

Gọi T là tổng số kẹo của n gói Chúng ta cần tìm số S lớn nhất thoả mãn: S ≤ T/2 Có một dãy con của dãy a có tổng bằng S Khi đó sẽ có cách chia với chênh lệch 2

phần là T - 2S là nhỏ nhất và dãy con có tổng bằng S ở trên gồm các phần tử là các gói

kẹo thuộc phần thứ nhất Phần thứ hai là các gói kẹo còn lại

b) Bài toán: Market (Olympic Balkan 2000)

Người đánh cá Clement bắt được n con cá, khối lượng mỗi con là ai, đem bán ngoài chợ ở chợ cá, người ta không mua cá theo từng con mà mua theo một lượng nào

đó Chẳng hạn 3 kg, 5kg

Ví dụ: có 3 con cá, khối lượng lần lượt là: 3, 2, 4 Mua lượng 6 kg sẽ phải lấy con cá thứ 2 và và thứ 3 Mua lượng 3 kg thì lấy con thứ nhất Không thể mua lượng 8

kg Nếu bạn là người đầu tiên mua cá, có bao nhiêu lượng bạn có thể chọn?

Ý tưởng thuật toán:

Thực chất bài toán là tìm các số S mà có một dãy con của dãy a có tổng bằng S

Ta có thể dùng phương pháp đánh dấu của bài chia kẹo ở trên rồi đếm các giá trị t mà L[t]=1

c) Bài toán: Điền dấu

Cho n số tự nhiên a1,a2, ,an Ban đầu các số được đặt liên tiếp theo đúng thứ tự cách nhau bởi dấu '?': a1?a2? ?an Cho trước số nguyên S, có cách nào thay các dấu '?' bằng dấu + hay dấu - để được một biểu thức số học cho giá trị là S không?

Ý tưởng thuật toán:

Đặt L(i,t)=1 nếu có thể điền dấu vào i số đầu tiên và cho kết quả bằng t Ta có công thức sau để tính L:

L(1,a[1]) =1

L(i,t)=1 nếu L(i - 1,t+a[i])=1 hoặc L(i - 1,t - a[i])=1

Nếu L(n,S)=1 thì câu trả lời của bài toán là có Khi cài đặt, có thể dùng một mảng 2 chiều (lưu toàn bộ bảng phương án) hoặc 2 mảng một chiều (để lưu dòng i và dòng i - 1) Chú ý là chỉ số theo t của các mảng phải có cả phần âm (tức là từ - T đến

T, với T là tổng của n số), vì trong bài này chúng ta dùng cả dấu - nên có thể tạo ra các tổng âm

Bài này có một biến thể là đặt dấu sao cho kết quả là một số chia hết cho k Ta

có thuật giải tương tự bài toán trên bằng cách thay các phép cộng, trừ bằng các phép cộng và trừ theo môđun k và dùng mảng đánh dấu với các giá trị từ 0 đến k - 1 (là các

số dư có thể có khi chia cho k) Đáp số của bài toán là L(n,0)

d) Bài toán: Expression (ACM 10690)

Trang 21

Cho n số nguyên Hãy chia chúng thành 2 nhóm sao cho tích của tổng 2 nhóm

là lớn nhất

Ý tưởng thuật toán:

Gọi T là tổng n số nguyên đó Giả sử ta chia dãy thành 2 nhóm, gọi S là tổng của một nhóm, tổng nhóm còn lại là T - S và tích của tổng 2 nhóm là S*(T - S) Bằng phương pháp đánh dấu ta xác định được mọi số S là tổng của một nhóm (như bài Market) và tìm số S sao cho S*(T - S) đạt max

1.5.3 Dạng 3: Xâu con chung dài nhất

L(i,j) = L(i - 1,j - 1)+1 nếu X[i] = Y[j]

L(i,j) = max(L(i - 1,j), L(i,j - 1)) nếu X[i] ≠ Y[j]

1.5.3 3 Cài đặt

Bảng phương án là một mảng 2 chiều L[0 m,0 n] để lưu các giá trị của hàm QHĐ L(i,j)

Đoạn chương trình cài đặt công thức QHĐ trên như sau:

for i:=0 to m do L[i,0]:=0;

Trang 22

P := L;

end;

1.5.3 4 Một số bài toán là biến thể cùng lớp của “Xâu con chung dài nhất”

a) Bài toán: Bắc cầu

Hai nước Anpha và Beta nằm ở hai bên bờ sông Omega, Anpha nằm ở bờ bắc

và có M thành phố được đánh số từ 1 đến m, Beta nằm ở bờ nam và có N thành phố được đánh số từ 1 đến n (theo vị trí từ đông sang tây) Mỗi thành phố của nước này thường có quan hệ kết nghĩa với một số thành phố của nước kia Để tăng cường tình hữu nghị, hai nước muốn xây các cây cầu bắc qua sông, mỗi cây cầu sẽ là nhịp cầu nối

2 thành phố kết nghĩa Với yêu cầu là các cây cầu không được cắt nhau và mỗi thành phố chỉ là đầu cầu cho nhiều nhất là một cây cầu, hãy chỉ ra cách bắc cầu được nhiều cầu nhất

Ý tưởng thuật toán:

Gọi các thành phố của Anpha lần lượt là a1, a2, am; các thành phố của Beta là

b1,b2, bn Nếu thành phố ai và bj kết nghĩa với nhau thì coi ai'bằng' bj Để các cây cầu không cắt nhau, nếu ta đã chọn cặp thành phố (ai, bj) để xây cầu thì cặp tiếp theo phải

là cặp (au,bv) sao cho u>i và v>j Như vậy các cặp thành phố được chọn xây cầu có thể coi là một dãy con chung của hai dãy a và b

Bài toán của chúng ta trở thành bài toán tìm dãy con chung dài nhất, ở đây hai phần tử 'bằng' nhau nếu chúng có quan hệ kết nghĩa

b) Bài toán: Biến đổi xâu

Cho 2 xâu X,Y Có 3 phép biến đổi với xâu X: chèn 1 kí tự, thay thế một kí tự hoặc xoá một kí tự Hãy tìm số ít nhất các phép biến đổi để biến xâu X thành xâu Y

Ý tưởng thuật toán:

Gọi F(i,j) là số phép biến đổi ít nhất để biến xâu X(i) gồm i kí tự phần đầu của

X (X(i)= X[1 i]) thành xâu Y(j) gồm j kí tự phần đầu của Y (Y(j) =Y[1 j]) Dễ thấy F(0,j)=j và F(i,0)=i

Nếu X[i]=Y[j] thì ta chỉ phải biến đổi xâu X(i-1) thành xâu Y(j-1) Do đó

F(i,j)=F(i-1,j-1)

Ngược lại, ta có 3 cách biến đổi:

Trang 23

- Xoá kí tự X[i] và biến đổi xâu X(i-1) thành Y(j) Khi đó F(i,j)=F(i-1,j)+1

- Thay thế X[i] bởi Y[j] và biến đổi X(i-1) thành Y(j-1) Khi đó 1)+1

F(i,j)=F(i-1,j Chèn Y[j] vào X(i) và biến đổi X(i) thành Y(jF(i,j)=F(i-1,j 1) Khi đó F(i,j)=F(i,jF(i,j)=F(i-1,j 1)+1 Tổng kết lại, ta có công thức QHĐ:

F(0,j)=j

F(i,0)=i

F(i,j) =F(i - 1,j - 1) nếu X[i] = Y[j]

F(i,j) = min(F(i - 1,j),F(i,j - 1),F(i - 1,j - 1))+1 nếu X[i] ≠ Y[j]

c) Bài toán: Palindrom (IOI 2000)

Một xâu gọi là xâu đối xứng (palindrom) nếu xâu đó đọc từ trái sang phải hay

từ phải sang trái đều như nhau Cho một xâu S, hãy tìm số kí tự ít nhất cần thêm vào S

để S trở thành xâu đối xứng

Ý tưởng thuật toán:

Gọi L(i,j) là số kí tự ít nhất cần thêm vào xâu con S[i j] của S để xâu đó trở thành đối xứng Đáp số của bài toán sẽ là L(1,n) với n là số kí tự của S

Ta có công thức sau để tính L(i,j):

L(i,i)=0

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

L(i,j)=max(L(i+1,j), L(i,j - 1)) nếu S[i] ≠ S[j]

1.5.4 Một số dạng khác:

- Liệt kê cấu hình, đếm số lượng cấu hình, tối ưu tổ hợp, di chuyển trên lưới ô vuông, biết cấu hình chỉ ra thứ tự từ điển và ngược lại, …

1.6 Hạn chế của quy hoạch động

 Việc tìm công thức truy hồi, phương trình truy toán hoặc tìm cách phân rã bài toán nhiều khi đòi hỏi sự phân tích tổng hợp rất công phu, dễ sai sót, khó nhận ra như thế nào là thích hợp, đòi hỏi nhiều thời gian suy nghĩ Đồng thời không phải lúc nào kết hợp lời giải của các bài toán con cũng cho kết quả của bài toán lớn hơn

 Khi bảng lưu trữ đòi hỏi mảng ba, bốn chiều, … thì khó có thể xử lý dữ liệu với kích cỡ mỗi chiều lớn hàng nghìn trở lên

 Có những bài toán không thể giải được bằng quy hoạch động

Trang 24

CHƯƠNG 2 - GIỚI THIỆU MỘT SỐ THUẬT TOÁN VÀ CẤU TRÚC DỮ LIỆU

ĐỂ KẾT HỢP VỚI PHƯƠNG PHÁP QUY HOẠCH ĐỘNG

Chương này nhằm giới thiệu một số bài toán, thuật toán quy hoạch động và cách kết hợp một số cấu trúc dữ liệu để thấy được hiệu quả của việc sử dụng phương pháp quy hoạch động

2.1 Bài toán 1: Phần thưởng

Tuấn là người chiến thắng trong một cuộc thi “tìm hiểu kiến thức vũ trụ” và được nhận các phần thưởng do công ty XYZ tài trợ Các phần thưởng được bố trí trên một bảng hình vuông n x n có dạng một lưới ô vuông kích thước đơn vị Các dòng của bảng được đánh số từ 1 đến n, từ trên xuống dưới và các cột của bảng được đánh số từ

1 đến n, từ trái qua phải Ô nằm trên giao của dòng i và cột j được gọi là ô (i,j) và trên

ô đó chứa một món quà có giá trị là a[i,j] (1 <= i, j <= n)

Để nhận phần thưởng, Tuấn được phép chọn một hình vuông kích thước k x k chiếm trọn trong một số ô của bảng và nhận tất cả các phần quà có trong các ô nằm trong hình vuông đó

Yêu cầu: Hãy xác định tổng giá trị lớn nhất của món quà mà Tuấn có thể nhận được

Dữ liệu vào:

 Dòng thứ nhất chứa hai sô nguyên dương n, k (n <= 1000, n/3 <= k <= n)

 Dòng thứ i trong số n dòng tiếp theo chứa n số nguyên dương, số thứ j là a[i,j] (a[i,j] <= 1000)

Kết quả: Ghi ra một số nguyên duy nhất là tổng giá trị lớn nhất của các món quà

mà Tuấn có thể nhận được

Ví dụ:

* Cách giải 1: Duyệt từng hình vuông có độ dài cạnh k, với i,j là cặp chỉ số góc

trên bên trái hình vuông và x,y là góc dưới phải hình vuông Với mỗi hình vuông ta tiến hành tính tổng của chúng và so sánh với Max (Max ban đầu bằng - ∞)

Trang 25

* Cách giải 2: Quy hoạch động

Gọi F[i,j] là tổng các giá trị từ ô[1,1] tới ô[i,j]

Tính tất cả các F[i,j] theo công thức truy hồi sau:

For i:=1 to n do

For j:=1 to n do

F[i,j]:=F[i,j-1] + F[i-1,j] + a[i,j] – F[i-1,j-1] ;

Sau khi tính, bảng F[i,j] có dạng nhƣ sau:

Giải thích:

Giả sử ô đang tính F[3,3] đƣợc tính bằng công thức truy hồi:

F[i,j]:=F[i,j-1] + F[i-1,j] + a[i,j] – F[i-1,j-1] ; F[3,3]:=F[3,2] + F[2,3] + a[3,3] – F[2,2]

Trang 26

For j:=k to n do

if Max < F[i,j] - F[i-k,j] - F[i,j-k] + F[i-k,j-k] then

Max:= F[i,j] - F[i-k,j] - F[i,j-k] + F[i-k,j-k];

2.2 Bài toán 2: Đoạn con liên tiếp có tổng lớn nhất

Cho dãy A gồm N số nguyên Tìm đoạn con (các phần tử liên tiếp) có tổng lớn nhất

For k:=i to j do T:=T +a[k];

If T > max then max:=T;

Trang 27

Như vậy, độ phức tạp thuật toán trong trường hợp này là O(n3

)

* Cách giải 2: Quy hoạch động

Gọi F1[i] là tổng lớn nhất trong đoạn A[1 i] (có thể không chứa A[i])

Để tính được F1[i] ta dùng thêm 1 mảng phụ F2 với ý nghĩa: F2[i] là tổng lớn nhất trong đoạn A[1 i] có chứa A[i]

Cơ sở quy hoạch động:

F1[0]=0 ; F2[0] = 0 ;

Công thức truy hồi:

F2[i] = Max(F2[i - 1] + A[i], A[i])

F1[i] = Max(F1[i - 1], F2[i])

Giải thích công thức truy hồi:

F2[i] := Max(A[i], A[i] + F2[i - 1]);

F1[i] := Max(F1[i - 1], F2[i]);

end;

Trang 28

Dựa vào quan hệ giữa F1[i - 1] và F2[i] để tìm ra phần tử cuối của đoạn con cần tìm Sau đó duyệt lui về 1 cho tới khi nào đạt được tổng lớn nhất (F1[n]) Độ phức tạp: O(n)

Cụ thể truy vết và xuất giá trị lớn nhất như sau:

res[k] := A[i]; {lưu phần tử được chọn vào dãy con}

i := i - 1; {lùi về vị trí liền kề trước}

end;

write('Doan Con La: (');

for i := k downto 2 do write(res[i], '; ');

2.3 Quy hoạch động dựa trên bài toán đã được sắp xếp

Trong thực tế có nhiều bài toán tối ưu mà thật khó để nhìn ra công thức truy hồi của nó Đối với các trường hợp như vậy, người ta thường thử sắp xếp bài toán đó theo một trong hai tiêu chí là tăng dần hoặc giảm dần với hy vọng có thể nhìn ra một hướng

Trang 29

để giải quyết Bởi dù sao thao tác trên các đối tượng đã biết trước được thứ tự của nó cũng dễ dàng hơn trên các đối tượng mà thứ tự của chúng là ngẫu nhiên

2.3.1 Sắp xếp

[1] Sắp xếp là bố trí lại vị trí các đối tượng của một danh sách theo một trật tự nhất định Sắp xếp đóng vai trò rất quan trọng trong cuộc sống nói chung và tin học nói riêng, thử hình dung xem, một cuốn từ điển, nếu các từ không được sắp xếp theo thứ tự , sẽ khó khăn như thế nào trong việc tra cứu các từ Theo D.Knuth thì 40% thời gian tính toán của máy tính là dành cho việc sắp xếp Không phải ngẫu nhiên thuật toán sắp xếp nhanh (Quick Sort) được bình chọn là một trong 10 thuật toán tiêu biểu của thế kỷ 20

Do đặc điểm dữ liệu (kiểu số hay phi số, kích thước bé hay lớn, lưu trữ ở bộ nhớ trong hay bộ nhớ ngoài, truy cập tuần tự hay ngẫu nhiên …) mà người ta có các thuật toán sắp xếp khác nhau Trong phạm vi luận văn này, tôi chỉ trình bày đến các thuật toán sắp xếp trong trường hợp dữ liệu được lưu trữ ở bộ nhớ trong (nghĩa là toàn

bộ dữ liệu cần sắp xếp phải được đưa vào bộ nhớ chính của máy tính)

2.3.2 Phát biểu bài toán

Giả sử các đối tượng cần sắp xếp được biểu diễn bởi bản ghi gồm một số trường Một trong các trường đó được gọi là khoá sắp xếp Kiểu của khoá là kiểu có thứ tự (chẳng hạn, kiểu số nguyên, kiểu số thực,…)

TArray = array[1 MAX]of object;

var a : TArray; n : longint;

Bài toán sắp xếp được phát biểu như sau: Cho mảng a các đối tượng, cần sắp xếp lại các thành phần (phần tử) của mảng a để nhận được mảng a mới với các thành phần

có các giá trị khoá tăng dần:

a[1].key <= a[2].key <= … <= a[n].key

2.3.3 Các thuật toán sắp xếp thông dụng

Hai thuật toán hay được sử dụng nhiều trong thực tế đó là thuật toán sắp xếp nổi bọt (BUBBLE SORT) và thuật toán sắp xếp nhanh (QUICK SORT)

2.3.3.1 Thuật toán sắp xếp nổi bọt (Bubble Sort)

Trang 30

Ý tưởng cơ bản của thuật toán là tìm và đổi chỗ các cặp phần tử kề nhau sai thứ

tự (phần tử đứng trước có khoá lớn hơn khoá của phần tử đứng sau) cho đến khi không tồn tại cặp nào sai thứ tự (dãy được sắp xếp)

Cụ thể:

- Lượt 1: ta xét từ cuối dãy, nếu gặp 2 phần tử kề nhau mà sai thứ tự thì đổi chỗ chúng cho nhau Sau lượt 1, phần tử có khoá nhỏ thứ nhất được đưa về vị trí 1

- Lượt 2: ta xét từ cuối dãy (chỉ đến phần tử thứ 2), nếu gặp 2 phần tử kề nhau

mà sai thứ tự thì đổi chỗ chúng cho nhau Sau lượt 2, phần tử có khoá nhỏ thứ hai được đưa về vị trí 2

- Lượt i: ta xét từ cuối dãy về (chỉ đến phần tử thứ i, vì phần đầu dãy từ 1 đến

i-1 đã được xếp đúng thứ tự), nếu gặp 2 phần tử kề nhau mà sai thứ tự thì đổi chỗ chúng cho nhau Sau lượt i, phần tử có khoá nhỏ thứ i được đưa về vị trí i

Xong lượt thứ n-1 thì dãy được sắp xếp xong

for j := n downto i+1 do

if a[j-1].key > a[j].key then begin

( ) ( ) ( )

Trang 31

Thuật toán có độ phức tạp O(n2

) Một thuật toán sắp xếp đơn giản, hay sử dụng khác cũng cho độ phức tạp O(n2

) for i:=1 to n – 1 do

for j:=i+1 to n do

if a[i].key>a[j].key then begin

tmp:=a[i];

a[i]:=a[j];

a[j]:=tmp;

end;

2.3.3.2 Thuật toán sắp xếp nhanh (Quick Sort)

Ý tưởng của Quicksort như sau

Để sắp xếp dãy coi như là sắp xếp đoạn từ chỉ số 1 đến chỉ số n Để sắp xếp một đoạn trong dãy, nếu đoạn chỉ có một phần tử thì dãy đã được sắp xếp, ngược lại ta chọn một phần tử x trong đoạn đó làm "chốt", mọi phần tử có khoá nhỏ hơn khoá của

“chốt” được xếp vào vị trí đứng trước chốt, mọi phần tử có khoá lớn hơn khoá của

“chốt” được xếp vào vị trí đứng sau chốt Sau phép hoán chuyển như vậy thì đoạn đang xét được chia làm hai đoạn mà mọi phần tử trong đoạn đầu đều có khoá khoá của “chốt” và mọi phần tử trong đoạn sau đều có khoá khoá của “chốt” Tiếp tục sắp xếp kiểu như vậy với 2 đoạn con, ta sẽ được đoạn đã cho được sắp xếp theo chiều tăng dần của khoá

Cụ thể:

Giả sử phải sắp xếp đoạn có chỉ số từ L đến H:

- Chọn x là một phần tử ngẫu nhiên trong đoạn L H (có thể chọn x là phần tử ở giữa đoạn, nghĩa là x = a[(L+H) div 2])

- Cho i chạy từ L sang phải, j chạy từ H sang trái; nếu phát hiện một cặp ngược thứ tự: i j và a[i].key >= x.key >=a[j].key thì đổi chỗ 2 phần tử đó; cho đến khi i>j Lúc đó dãy ở tình trạng: khoá các phần tử đoạn L i khoá của x; khoá của các phần

tử đoạn j H khoá của x Tiếp tục sắp xếp như vậy với 2 đoạn L j và i H

Thủ tục QuickSort(L,H) sau, sắp xếp đoạn từ L tới H, để sắp xếp dãy số ta gọi QuickSort(1,n)

procedure QuickSort(L,H:longint);

var i,j :longint;

x,tmp :object;

Trang 32

while a[i].key<x.key do inc(i);

while a[j].key>x.key do dec(j);

- Có thời gian thực thi cỡ O(nlogn) trong trường hợp trung bình

- Có thời gian thực thi cỡ O(n2) trong trường hợp xấu nhất (2 đoạn được chia thành một đoạn n-1 và một đoạn 1 phần tử) Khả năng để xảy ra trường hợp này là rất

ít, còn nếu chọn chốt ngẫu nhiên, hầu như sẽ không xảy ra

Nhận xét

Nếu chương trình ít gọi tới thủ tục sắp xếp và chỉ trên tập dữ liệu nhỏ, thì việc

sử dụng một thuật toán phức tạp (tuy có hiệu quả hơn) có thể không cần thiết, khi đó

có thể sử dụng thuật toán đơn giản có độ phức tạp O(n2), dễ cài đặt Tuy nhiên, vì độ phức tạp O(n2

), nghĩa là thời gian thực hiện tăng lên gấp 4 khi số lượng phần tử tăng lên gấp đôi Do đó, trong trường hợp sắp xếp trên tập dữ liệu lớn nên sử dụng thuật toán sắp xếp nhanh có độ phức tạp cỡ O(nlogn)

Trang 33

2.3.3.4 Sắp xếp bằng đếm phân phối (Distribution Counting)

Trong trường hợp khoá các phần tử a[1], a[2] , , a[n] là các số nguyên nằm trong khoảng từ 0 tới K ta có thuật toán đơn giản và hiệu quả như sau:

Xây dựng dãy c[0], c[1], … , c[K] , trong đó c[V] là số lần xuất hiện khoá V trong dãy

for V := 0 to K do c[V] := 0; {Khởi tạo dãy c}

for i := 1 to n do c[a[i].key] := c[a[i].key] + 1;

Như vậy, sau khi sắp xếp:

- Các phần tử có khóa bằng 0 đứng trong đoạn từ vị trí 1 tới vị trí c[0]

- Các phần tử có khóa bằng 1 đứng trong đoạn từ vị trí c[0] + 1 tới vị trí c[0] +

Dãy khoá sau khi sắp xếp: 0, 0, 1, 2, 2, 2, 3, 5

Độ phức tạp của thuật toán là: O(max(N,K))

2.3.3.5 Một số bài toán

Sau đây là một số bài toán đòi hỏi phải sắp xếp trước khi có thể quy hoạch động

Bài 1: Robot

Một cuộc trình diễn sáng tạo robot có N robot tham gia (các robot được đánh số

từ 1 đến N) Địa hình trình diễn là một sân phẳng đã được vạch thành N tuyến song song, mỗi tuyến là đủ dài để các robot có thể trổ tài Tại vạch xuất phát, mỗi tuyến đều

Trang 34

có gắn 1 bảng điện tử cho biết tọa độ của robot trên tuyến tương ứng Tọa độ này là những số nguyên biểu thị khoảng cách robot đến vạch xuất phát

Tại thời điểm G, tọa độ của robot i đang là ai (i=1,2, ,N), Ban tổ chức công bố một bộ gồm M thẻ lệnh, mỗi thẻ ghi một số nguyên bj (j=1,2, ,M) và yêu cầu các robot phải phối hợp phân công để mỗi robot được nhận một thẻ rồi đi chuyển đến tọa

độ ghi trong thẻ Chi phí mà một robot di chuyển từ từ tọa độ x đến tọa độ y được tính

là giá trị tuyệt đối của hiệu a-b Ban tổ chức sẽ đánh giá độ thông minh của các robot thông qua tổng chi phí S mà các robot phải chi phí cho việc di chuyển, theo tiêu chí: S càng nhỏ thì cảng được đánh giá cao

Yêu cầu: Cho biết tọa độ tại thời điểm G của N robot, M giá trị ghi trong M thẻ

lệnh của ban tổ chức, hãy cho biết giá trị nhỏ nhất của S mà các robot có thể đạt được

Dữ liệu:

+ Dòng đầu tiên ghi lần lượt hai số nguyên dương M, N(1<=N<=M<=1000) + Dòng thứ 2 ghi M số nguyên b1, b2, ,bM

+ Dòng thứ 3 ghi N số nguyên a1, a2, ,aN

Tất cả các số ai, bj, đều nguyên và nằm trong khoảng từ 0 đến 10000

Kết quả: Ghi ra duy nhất số nguyên S tìm được

2 Chú ý: Hơn 50% test có M<=100

Thuật toán quy hoạch động như sau

 Sắp xếp mảng tọa độ a, b tăng dần (Dùng Quick Sort)

 Gọi F[i,j] là chi phí nhỏ nhất để i robot di chuyển trong j vị trí cho trước:

Vì đã sắp xếp trước tọa độ của các robot và các thẻ nên:

- Ta có: F[0,0]=0; F[0,1]=0; F[0,2]=0;

Trường hợp 1: 1 robot và nhiều thẻ

- Nếu có 1 robot và 1 thẻ thì : F[1,1]=F[0,0] + abs(a[1]-b[1])

- Nếu có 1 robot và 2 thẻ thì F[1,2]=min (F[1,1], F[0,1] + abs(a[1]-b[2]))

- Nếu có 1 robot và 3 thẻ thì F[1,3]=min (F[1,2], F[0,2] + abs(a[1]-b[3]))

-

Trường hợp 2: nhiều robot và nhiều thẻ

Trang 35

- Nếu có 2 robot và 2 thẻ thì F[2,2]=F[1,1] + abs(a[2]-b[2])

- Nếu có 2 robot và 3 thẻ thì F[2,3]=min (F[2,2], F[1,2] + abs(a[2]-b[3]))

- Nếu có 2 robot và 4 thẻ thì F[2,4]=min (F[2,3], F[1,3] + abs(a[2]-b[4]))

- …

Từ đó ta suy ra công thức truy hồi

F[i,i]:= F[i-1,i-1] + abs(x[i] – y[i]), với mọi i trong khoảng [1 n]

F[i,j]:= min(F[i,j-1], F[i-1,j-1] + abs(x[i] – y[j]), với mọi i thuộc khoảng [1 n] và j thuộc [i+1 m]

Kết quả = F[n,m]

* Ghi chú: abs(x) là hàm cho giá trị tuyệt đối của biểu thức x trong Pascal

Ví dụ: File dữ liệu vào Robot.inp có cấu trúc như sau:

Sau khi chạy chương trình, 2 mảng dữ liệu vào a và b có kết quả như sau:

Bảng phương án F sau khi tính có kết quả như sau:

Hình 2.4 Kết quả bảng phương án F[n,m] bài “Robot”

Truy vết để đạt được kết quả tối ưu là 11 như sau:

F[5,6]=11, có nghĩa là robot số 5 di chuyển đến thẻ thứ 6, để lùi về dòng trên ta thực hiện kiểm tra F[i-1,j] = F[5,6] – abs(a[5] – b[6])  11 – 2 = 9 Đánh dấu cặp (robot 5, thẻ 6) Ta được F[4,5] = 9 là kết quả tối ưu liền trước Tiếp tục truy ngược

1 2 3 4 5

a 3 6 10 25 30

1 2 3 4 5 6

b 1 5 9 12 20 28

Trang 36

- F[4,5] – abs(a[4] – b[5])  9 – 5 = 4 Đánh dấu cặp (robot 4, thẻ 5) Ta được F[3,3]

- F[3,3] – abs(a[3] – b[3])  4 – 1 = 3 Đánh dấu cặp (robot 3, thẻ 3) Ta được F[2,2]

- F[2,2] – abs(a[2] – b[2])  3 – 1 = 2 Đánh dấu cặp (robot 2, thẻ 2) Ta được F[1,1]

- F[1,1] – abs(a[1] – b[1])  2 – 2 = 0 Đánh dấu cặp (robot 1, thẻ 1) Ta được F[0,0]

- Dừng Xuất các mảng đánh dấu theo chiều ngược lại

Bài 2: Đoạn gối nhau dài nhất

Cho N đoạn thẳng trên trục số với các điểm đầu ai và điểm cuối bi là những số nguyên trong khoảng 1000 1000, ai < bi Hãy tìm số lượng tối đa K đoạn thẳng gối nhau liên tiếp Hai đoạn thẳng [a,b] và [c,d] được gọi là gối nhau nếu xếp chúng trên cùng một trục số thì điểm đầu đoạn này trùng với điểm cuối của đoạn kia, tức là c = b hoặc d = a

Dữ liệu vào: tệp văn bản DOAN.INP gồm

- Dòng đầu số N cho biết tổng các đoạn

- N dòng tiếp theo , mỗi dòng cho biết 2 số nguyên là điểm đầu ai

và điểm cuối bi

- Các số trên cùng một dòng cách nhau ít nhất một khoảng cách

Dữ liệu ra: tệp văn bản DOAN.OUT chứa:

- Duy nhất một số nguyên cho biết số lượng tối đa các đoạn tìm được

Ví dụ trên cho biết có tối đa 3 đoạn gối nhau liên tiếp là [1,3], [3,4] và [4,5]

Thuật toán quy hoạch động như sau

Để có thể quy hoạch động trước tiên ta cần sắp xếp tăng dần các đoạn theo đầu phải của chúng Sau đó tiến hành quy hoạch như sau:

 Gọi L[i] là số lượng tối đa các đoạn gối nhau tính từ 1 đến i

Trang 37

 Ban đầu độ dài tối đa tại đoạn thứ i là 1 (vì chỉ có chính nó) Đây là bài toán cơ

sở quy hoạch động

 Với mỗi đoạn thứ i, ta tìm tất cả các đoạn thứ j (j=1 i-1) mà có điểm cuối = điểm đầu của i và độ dài L[j] là lớn nhất Nếu thỏa mãn thì ta thực hiện gán L[i]:=L[j]+1(độ dài của đoạn thứ i bằng độ dài của đoạn thứ j +1 (j đang là dài nhất) ) Cụ thể đoạn code để tính bảng phương án như sau:

for i:=1 to n do begin

Code đoạn xuất giá trị đoạn con dài nhất và truy vết như sau:

Trang 38

for i:=n downto 1 do if s[i].c>0 then writeln(g,s[i].d,' , ',s[i].c);

2.4 Quy hoạch động kết hợp xử lý Bit để mô tả trạng thái bài toán

2.4.1 Bit và các thao tác xử lý Bit

2.4.1.1 Quy ước về vị trí của các bit

Mỗi byte bao gồm 8 bit được mã số từ phải sang trái còn gọi là bit thấp đến bit cao [4] Bit nằm ở bên phải được xem là thấp hơn bit nằm ở bên trái Các bit được đánh số như sau: 7 6 5 4 3 2 1 0

Mỗi bit có thể nhận 1 trong 2 giá trị là 0 hoặc 1 Tại mỗi thời điểm thực hiện chương trình mỗi bit được nhận giá trị xác định Mọi số nguyên trong máy đều biểu diễn dưới dạng nhị phân, ví dụ số 19 được biểu diễn như sau:

b Phép cộng logic trên các bit (OR)

Thực hiện trên từng cặp bit tương ứng của các toán hạng theo bảng cộng sau:

bit a b a OR b

0 0 0

0 1 1

Trang 39

c Phép nhân logic trên các bit AND:

Thực hiện trên từng cặp bit tương ứng của các toán hạng theo bảng nhân sau:

d Phép cộng loại trừ trên các bit (XOR)

Thực hiện trên từng cặp bit tương ứng của các toán hạng theo bảng sau:

Trang 40

a Lấy bit của một số nguyên

Hàm getbit(x,i) cho giá trị của bit thứ i (tính từ phải sang trái) của số nguyên x

Ngày đăng: 27/04/2021, 16:26

HÌNH ẢNH LIÊN QUAN

2.1  Bảng minh họa kết quả bài toán “Phần thưởng”  15 - Phương pháp quy hoạch động và vận dụng kết hợp giải các bài toán chuyên tin bậc thpt
2.1 Bảng minh họa kết quả bài toán “Phần thưởng” 15 (Trang 8)
2.6  Đồ thị biểu diễn đường đi giữa các thành phố bài toán - Phương pháp quy hoạch động và vận dụng kết hợp giải các bài toán chuyên tin bậc thpt
2.6 Đồ thị biểu diễn đường đi giữa các thành phố bài toán (Trang 9)
Hình 1.1 Các tiêu chí của bài toán tối ưu thường là chi phí hoặc giá trị - Phương pháp quy hoạch động và vận dụng kết hợp giải các bài toán chuyên tin bậc thpt
Hình 1.1 Các tiêu chí của bài toán tối ưu thường là chi phí hoặc giá trị (Trang 12)
Bảng phương án F sau khi tính có kết quả như sau: - Phương pháp quy hoạch động và vận dụng kết hợp giải các bài toán chuyên tin bậc thpt
Bảng ph ương án F sau khi tính có kết quả như sau: (Trang 35)
Hình 2.4 Bảng phương án tính F[n,x] của bài “Chọn ô”. - Phương pháp quy hoạch động và vận dụng kết hợp giải các bài toán chuyên tin bậc thpt
Hình 2.4 Bảng phương án tính F[n,x] của bài “Chọn ô” (Trang 45)
Hình 2.5 Bảng lưu vết bài “Chọn ô” - Phương pháp quy hoạch động và vận dụng kết hợp giải các bài toán chuyên tin bậc thpt
Hình 2.5 Bảng lưu vết bài “Chọn ô” (Trang 47)
Hình 2.6 Đồ thị biểu diễn đường đi giữa các thành phố bài toán “Sherry” - Phương pháp quy hoạch động và vận dụng kết hợp giải các bài toán chuyên tin bậc thpt
Hình 2.6 Đồ thị biểu diễn đường đi giữa các thành phố bài toán “Sherry” (Trang 49)
Hình 2.7 Các bảng Fx, vet, V thể hiện quá trình truy vết cho bài toán “Sherry” - Phương pháp quy hoạch động và vận dụng kết hợp giải các bài toán chuyên tin bậc thpt
Hình 2.7 Các bảng Fx, vet, V thể hiện quá trình truy vết cho bài toán “Sherry” (Trang 50)
Hình 3.1 Kết quả chạy chương trình với m = 6 và n=5, bài “Robot”. - Phương pháp quy hoạch động và vận dụng kết hợp giải các bài toán chuyên tin bậc thpt
Hình 3.1 Kết quả chạy chương trình với m = 6 và n=5, bài “Robot” (Trang 54)
Hình 3.2 Kết quả chạy chương trình với n=5, bài “Đoạn con gối nhau dài nhất”. - Phương pháp quy hoạch động và vận dụng kết hợp giải các bài toán chuyên tin bậc thpt
Hình 3.2 Kết quả chạy chương trình với n=5, bài “Đoạn con gối nhau dài nhất” (Trang 54)
Hình 3.3 Kết quả chạy chương trình bằng PP QHĐ kết hợp bit với n=3, bài “Chọn ô”. - Phương pháp quy hoạch động và vận dụng kết hợp giải các bài toán chuyên tin bậc thpt
Hình 3.3 Kết quả chạy chương trình bằng PP QHĐ kết hợp bit với n=3, bài “Chọn ô” (Trang 55)
Hình 3.6 Kết quả chạy chương trình bằng PP QHĐ thông thường với n=20, bài “Chọn ô”. - Phương pháp quy hoạch động và vận dụng kết hợp giải các bài toán chuyên tin bậc thpt
Hình 3.6 Kết quả chạy chương trình bằng PP QHĐ thông thường với n=20, bài “Chọn ô” (Trang 56)
Hình 3.5 Kết quả chạy chương trình bằng PP QHĐ kết hợp bit với n=20, bài “Chọn ô”. - Phương pháp quy hoạch động và vận dụng kết hợp giải các bài toán chuyên tin bậc thpt
Hình 3.5 Kết quả chạy chương trình bằng PP QHĐ kết hợp bit với n=20, bài “Chọn ô” (Trang 56)
Hình 3.7 Kết quả chạy chương trình bằng PP QHĐ kết hợp bit với n=6, bài “Sherry”. - Phương pháp quy hoạch động và vận dụng kết hợp giải các bài toán chuyên tin bậc thpt
Hình 3.7 Kết quả chạy chương trình bằng PP QHĐ kết hợp bit với n=6, bài “Sherry” (Trang 57)
Hình 3.8 Kết quả chạy chương trình bằng PP Duyệt quay lui với n=6, bài “Sherry”. - Phương pháp quy hoạch động và vận dụng kết hợp giải các bài toán chuyên tin bậc thpt
Hình 3.8 Kết quả chạy chương trình bằng PP Duyệt quay lui với n=6, bài “Sherry” (Trang 57)

TỪ KHÓA LIÊN QUAN

TÀI LIỆU CÙNG NGƯỜI DÙNG

TÀI LIỆU LIÊN QUAN

🧩 Sản phẩm bạn có thể quan tâm

w