Đề Cương Ôn Tập Phân Tích Thiết Kế Thuật Toán

39 4 0
Tài liệu đã được kiểm tra trùng lặp
Đề Cương Ôn Tập Phân Tích Thiết Kế Thuật Toán

Đ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

Đề cương chủ yếu về 4 thuật toán: Tham Lam, Chia Để Trị, Quay Lui và Quy Hoạch Động. Ngoài lý thuyết đơn giản ra, đề cương có 31 bài tập, không có đề bài, chỉ bao gồm ý tưởng giải, ví dụ đơn giản và code lập trình bằng C++ đầy đủ.

Trang 2

LÝ THUYẾT Định Lý Thợ

Dạng 2: d(n) có dạng log (ko phải hàm nhân) Giả thiết n = bk => k = logbn

=> Nghiệm thuần nhất n^(logba)

Tính nghiệm riêng = ∑𝑘−1𝑗=0 𝑎𝑗𝑑(𝑏𝑘−𝑗)

Tổng dãy số cách đều = (số đầu+số cuối) * số số hạng /2

Xét nghiệm riêng và nghiệm thuần nhất, T(n) = giá trị nghiệm cao nhất

Chia để trị

Áp dụng cho các bài toán có thể giải quyết bằng cách:  Chia nhỏ ra thành các bài toán con

 Giải quyết các bài toán con

 Lời giải của các bài toán con được tổng hợp lại thành lời giải cho bài toán ban đầu  Các bài toán con sẽ được chia thành các bài toán nhỏ hơn nữa

 Dừng lại khi kích thước bài toán đủ nhỏ mà ta có thể giải dễ dàng bài toán cơ sở

Quy hoạch động

Một số thuật ngữ

◦ Bài toán giải theo phương pháp quy hoạch động được gọi là bài toán quy hoa ̣ch động

Trang 3

◦ Công thức phối hợp nghiệm của các bài toán con để có nghiệm của bài toán lớn gọi là công thức truy hồi của quy hoạch động

◦ Tập các bài toán nhỏ nhất có ngay lời giải để từ đó giải quyết các bài toán lớn hơn gọi là cơ sở của quy hoa ̣ch động

◦ Không gian lưu trữ lời giải các bài toán con để tìm cách phối hợp chúng gọi là bảng quy hoạch hay bảng phương án của quy hoạch động

◦ Tính chất thứ nhất và thứ hai là điều kiện cần của một bài toán quy hoạch động

◦ Tính chất thứ ba nêu lên đặc điểm của một bài toán mà cách giải bằng phương pháp quy hoạch động hiệu quả hơn hẳn so với phương pháp giải đệ quy thông thường

◦ Khác với thuật toán đệ quy, phương pháp quy hoạch động thêm vào cơ chế lưu trữ nghiệm hay một phần nghiệm của mỗi bài toán khi giải xong nhằm mục đích sử dụng lại, hạn chế những thao tác thừa trong quá trình tính toán

Mục đích: Cải tiến thuật toán chia để trị hoặc quay lui vét cạn để giảm thời gian thực hiện Ý tưởng: Lưu trữ các kết quả của các bài toán con trong bảng quy hoạch Đổi bộ nhớ lấy

 Thử các lựa chọn còn lại tại bước này

 Phù hợp với bài toán liệt kê cấu hình dạng X[1, , n]

Trang 5

Tham Lam

1 Cái ba lô

Trang 7

2 Lập lịch

Trang 8

3 Sắp xếp môn học

Đoạn code trên giải quyết bài toán lựa chọn các khóa học sao cho số lượng khóa học được chọn là lớn nhất, mà không có hai khóa học nào trùng thời gian Ý tưởng chính của phương pháp Greedy trong đoạn code này là sắp xếp các khóa học theo thời gian kết thúc tăng dần, sau đó lựa chọn lần lượt các khóa học không trùng thời gian với nhau

Giả sử có 5 khóa học như sau:

Khóa học 1 (id=1): bắt đầu lúc 6, kết thúc lúc 7 Khóa học 2 (id=2): bắt đầu lúc 7, kết thúc lúc 9 Khóa học 3 (id=3): bắt đầu lúc 8, kết thúc lúc 14 Khóa học 4 (id=4): bắt đầu lúc 10, kết thúc lúc 20 Khóa học 5 (id=5): bắt đầu lúc 9, kết thúc lúc 12

Sử dụng phương pháp Greedy, ta sẽ sắp xếp các khóa học theo thời gian kết thúc tăng dần

Trang 9

Sau khi sắp xếp, ta lựa chọn lần lượt các khóa học không trùng thời gian với nhau Trong ví dụ này, ta sẽ lựa chọn các khóa học sau: 1, 2, 5, 4 Do đó, số lượng khóa học được chọn là 4 và đây là lịch trình tối ưu

4 Đóng thùng

Ý tưởng chính của thuật toán là sắp xếp các đồ vật theo thứ tự giảm dần của kích thước, sau đó lần lượt đặt từng đồ vật vào thùng có thể chứa được nó Nếu không thể đặt vào thùng hiện tại, thì tìm thùng trống khác có thể chứa được và đặt đồ vật vào đó

Trang 10

Giả sử có các đồ vật có kích thước là {3, 2, 5, 1, 4, 3} và kích thước của thùng là 6 Chương trình sẽ thực hiện như sau:

Sau khi sắp xếp: {5, 4, 3, 3, 2, 1} Lần lượt đặt các đồ vật vào thùng: Thùng 1: {5}, còn lại kích thước 1 Thùng 2: {4, 1}, còn lại kích thước 1 Thùng 3: {3, 3}, còn lại kích thước 0 Thùng 4: {2}, còn lại kích thước 4

Trang 11

5 Rút tiền

Sắp xếp các mệnh giá tiền giảm dần: Trước tiên, danh sách các mệnh giá tiền được sắp xếp theo thứ tự giảm dần, từ mệnh giá lớn nhất đến nhỏ nhất Điều này giúp chương trình rút tiền bằng các tờ tiền có mệnh giá lớn trước, giảm thiểu số lượng tờ tiền cần rút

Rút tiền từ mệnh giá lớn nhất đến nhỏ nhất: Thuật toán lặp qua từng mệnh giá tiền từ lớn nhất đến nhỏ nhất Với mỗi mệnh giá, nó tính số tờ tiền cần rút bằng cách chia số tiền cần rút cho mệnh giá đó và lấy phần nguyên của kết quả Sau đó, cập nhật số tiền cần rút cho lần lặp tiếp theo

Giả sử danh sách các mệnh giá tiền có sẵn là {100,000, 50,000, 40,000, 20,000, 10,000}, và người dùng muốn rút 180,000 VND từ máy ATM

Trang 12

Bắt đầu với mệnh giá 100,000 VND:

Số tờ tiền cần rút = 180,000 / 100,000 = 1 (phần nguyên) Cập nhật số tiền cần rút: 180,000 - 1 * 100,000 = 80,000 VND Tiếp tục với mệnh giá 50,000 VND:

Số tờ tiền cần rút = 80,000 / 50,000 = 1 (phần nguyên)

Cập nhật số tiền cần rút: 80,000 - 1 * 50,000 = 30,000 VND …

Trang 13

6 Trồng hoa

Trang 15

 Bước 3: Kiểm tra xem vị trí đó có phù hợp để đặt quân hậu không bằng cách kiểm tra

các quân hậu đã đặt trước đó Nếu vị trí đó hợp lệ, tiến hành đặt quân hậu và gọi đệ quy để thử vị trí tiếp theo

 Bước 4: Nếu đã đặt quân hậu vào vị trí cuối cùng trên bàn cờ (i == n), thì in ra cách xếp

hậu đó

 Bước 5: Lặp lại các bước trên cho tất cả các quân hậu cho đến khi tìm được tất cả các

cách xếp hậu đúng trên bàn cờ hoặc không còn cách nào thỏa mãn

Trang 17

2 Dãy nhị phân

Thuật toán quay lui được sử dụng để sinh ra tất cả các tổ hợp nhị phân có độ dài n Ý tưởng chính của thuật toán là sử dụng một mảng để lưu trữ các giá trị 0 và 1, mỗi giá trị tại một vị trí của mảng biểu diễn cho một bit trong tổ hợp nhị phân Thuật toán sẽ thử tất cả các kết hợp có thể của các bit này, từ bit đầu tiên đến bit cuối cùng, và đệ quy tiến hành thử các giá trị có thể của bit tiếp theo cho đến khi đạt tới bit cuối cùng Khi đạt đến bit cuối cùng, thuật toán sẽ in ra kết quả và quay lui để thử các giá trị khác cho các bit trước đó

Dưới đây là các bước cụ thể của thuật toán:

- Khởi tạo một mảng có độ dài n để lưu trữ các giá trị của tổ hợp nhị phân

- Gọi hàm quay lui với các tham số là mảng đã khởi tạo, chỉ số của bit hiện tại (bắt đầu từ 1), và độ dài của tổ hợp nhị phân

- Trong hàm quay lui:

- Lặp qua các giá trị có thể của bit hiện tại (0 hoặc 1) - Gán giá trị cho bit hiện tại

- Nếu đã đạt tới bit cuối cùng, in ra tổ hợp nhị phân và kết thúc

- Nếu chưa đạt tới bit cuối cùng, gọi đệ quy để thử các giá trị cho bit tiếp theo

- Khi đã thử hết tất cả các giá trị cho bit hiện tại, quay lui để thử các giá trị khác cho bit trước đó

Trang 18

Các bước giải: a Khởi tạo mảng x[] và b[] với giá trị ban đầu b Tạo hàm output() để in ra

một hoán vị c Tạo hàm đệ quy hoanvi() để sinh ra tất cả các hoán vị:

- Với mỗi vị trí i từ 1 đến n, thử tất cả các số chưa được chọn để điền vào vị trí i - Đánh dấu số đã chọn và gọi đệ quy để điền số tiếp theo

- Khi đã điền đủ n số, in ra hoán vị đó

- Hủy đánh dấu số đã chọn để thử các số khác d Gọi hàm hoanvi() từ main() để bắt đầu

sinh và in ra tất cả các hoán vị của các số từ 1 đến n

Trang 19

4 Mã đi tuần

Trang 20

5 Mã đi tuần theo chu trình đóng Ý tưởng:

- Sử dụng một ma trận A[][] để lưu vị trí các bước di chuyển trên bàn cờ - Sử dụng hai mảng X[] và Y[] để định nghĩa các hướng di chuyển từ mỗi ô - Sử dụng biến dem để đếm số bước đã đi

- Sử dụng biến x_first và y_first để lưu vị trí ban đầu

- Sử dụng hàm xuat() để in ra bàn cờ sau mỗi bước di chuyển

- Sử dụng hàm diChuyen() để thực hiện việc di chuyển từ vị trí hiện tại đến các vị trí khác trên bàn cờ, đồng thời kiểm tra xem mã đã đi hết các ô chưa và đã trở về vị trí ban đầu chưa

Trang 21

6 Tổng các tập con

Trang 22

7 Sudoku

- Kiểm tra tính hợp lệ của giá trị trong ô: kiểm tra xem có thể đặt giá trị k vào vị trí (x,

y) trên bảng Sudoku hay không Kiểm tra xem giá trị k đã tồn tại trong hàng, cột hoặc ô 3x3 chứa vị trí (x, y) chưa Nếu không hợp lệ, trả về 0; ngược lại trả về 1

- Giải bài toán Sudoku bằng đệ quy: Sử dụng phương pháp đệ quy để thử tất cả các giá

trị từ 1 đến 9 cho ô hiện tại và tiếp tục đệ quy để thử giá trị tiếp theo cho ô kế tiếp Nếu không tìm thấy giải pháp, quay lui và thử các giá trị khác cho ô hiện tại

- Tìm kiếm giải pháp: kết thúc cột hiện tại, kiểm tra xem đã đến cuối bảng chưa Nếu đã

đến cuối bảng, in ra giải pháp và kết thúc chương trình Nếu chưa, sẽ tiếp tục đệ quy với hàng tiếp theo Nếu ô hiện tại đã có giá trị, nó sẽ tiếp tục đệ quy với ô kế tiếp Nếu ô hiện

tại chưa có giá trị, nó sẽ thử tất cả các giá trị hợp lệ cho ô đó

Trang 23

8 Tổ hợp chập k của n

Trang 24

Quy hoạch động

Ý tưởng chính là sử dụng một bảng hoặc một mảng để lưu trữ kết quả của các bài toán con nhỏ

 Ta bắt đầu với các trường hợp cơ bản: C(n, 0) = C(n, n) = 1

 Sau đó, ta sử dụng công thức tổ hợp: C(n, k) = C(n-1, k-1) + C(n-1, k) để tính toán các giá trị còn lại

 Bằng cách tính toán từ trên xuống dưới và từ trái sang phải, ta có thể xây dựng bảng hoặc mảng chứa kết quả của tất cả các bài toán con nhỏ

 Kết quả cuối cùng sẽ nằm ở ô góc phải dưới cùng của bảng hoặc mảng

Trang 25

2 Dãy Fibonacci

Khởi tạo mảng F và giá trị ban đầu của dãy Fibonacci: Mảng F được khai báo với kích thước n và được sử dụng để lưu trữ các số trong dãy Fibonacci Ban đầu, hai phần tử đầu tiên của dãy Fibonacci là 0 và 1 được gán trực tiếp vào F[0] và F[1]

Duyệt qua từng phần tử của dãy Fibonacci từ 2 đến n: Sử dụng một vòng lặp, với mỗi giá trị i từ 2 đến n, tính giá trị của F[i] bằng cách cộng hai giá trị trước đó của dãy Fibonacci, tức là F[i-1] và F[i-2]

In ra dãy Fibonacci: Cuối cùng, dãy Fibonacci được in ra màn hình từ F[0] đến F[n]

3 Tổng tập con

Trang 26

Sử dụng bảng hoặc mảng: Bước đầu tiên là tạo một bảng hoặc mảng 1 chiều để lưu trữ kết quả của các bài toán con nhỏ Mỗi phần tử trong mảng này thường là một giá trị boolean, chỉ ra xem có thể tạo thành tổng mục tiêu từ một tập con của dãy ban đầu hay không

Trường hợp cơ bản: Khởi tạo các giá trị cơ bản của bảng hoặc mảng Ví dụ, nếu mục tiêu là 0, thì tất cả các giá trị trong mảng này đều là True vì có thể tạo ra tổng 0 từ bất kỳ tập con nào (bằng cách không chọn phần tử nào)

Tính toán các giá trị còn lại: Sử dụng phương pháp quy hoạch động, tính toán các giá trị còn lại của bảng hoặc mảng dựa trên giá trị của các bài toán con nhỏ hơn Mỗi ô của bảng hoặc mảng thường được tính toán dựa trên hai trường hợp: (a) nếu không bao gồm phần tử hiện tại, (b) nếu bao gồm phần tử hiện tại

Trả về kết quả: Kết quả cuối cùng thường được lấy từ ô cuối cùng của bảng hoặc mảng Nếu giá trị tại ô này là True, có nghĩa là có thể tạo thành tổng mục tiêu từ một tập con của dãy ban đầu

Trang 27

4 Cái ba lô

Ý tưởng giải bài toán:

Xây dựng bảng: Tạo một bảng 2 chiều có kích thước n x W, trong đó n là số lượng đồ vật và W là trọng lượng tối đa của cái ba lô

Khởi tạo giá trị ban đầu: Đặt tất cả các giá trị trong hàng đầu tiên và cột đầu tiên của bảng là 0

Tính toán giá trị tối ưu: Sử dụng công thức tối ưu L[i][t] = max(L[i - 1][t], L[i][t-g[i]] + v[i]), trong đó v [i] là giá trị của đồ vật thứ i, g[i] là trọng lượng của đồ vật thứ i, và L[i][t] là giá trị tối ưu có thể đạt được với i đồ vật và trọng lượng t

Trả về giá trị tối ưu: Giá trị tối ưu cuối cùng sẽ nằm ở ô góc dưới cùng bên phải của bảng

Trang 28

5 Dãy con tăng dài nhất

Ý tưởng giải bài toán:

Khởi tạo mảng L để lưu độ dài của dãy con tăng dài nhất kết thúc tại mỗi vị trí của dãy Bổ sung phần tử ảo INT_MAX vào cuối dãy A

Duyệt qua từng phần tử của dãy, cập nhật giá trị của L[i] bằng cách so sánh với các phần tử

Trang 29

Trả về độ dài của dãy con tăng dài nhất và in ra dãy con đó Lập bảng quy hoạch

| 3 4 2 8 10 5 1 ∞ - 1 | 1 1 1 1 1 1 1 1 1 2 2 3 4 3 2 1

Trang 30

6 Đổi tiền

Khởi tạo mảng P và L: Mảng P được khởi tạo với giá trị INT_MAX, đại diện cho số lượng đồng tiền ít nhất cần để đổi đến số tiền tương ứng Mảng L cũng được khởi tạo tương tự nhưng có thêm phần tử 0 ở đầu

Duyệt qua từng loại đồng tiền và mỗi mức số tiền từ 1 đến M: Tại mỗi bước lặp, ta cập nhật mảng L dựa trên mảng P, sử dụng các loại đồng tiền hiện có

Cập nhật mảng L: Tại mỗi mức số tiền t, ta cập nhật L[t] bằng giá trị nhỏ nhất giữa P[t] (số lượng đồng tiền ít nhất cho số tiền t mà không sử dụng đồng tiền hiện tại) và L[t-a[i]] + 1 (số lượng đồng tiền ít nhất cho số tiền t - a[i] cộng thêm một đồng tiền hiện tại)

Trả về kết quả: Trả về giá trị cuối cùng của L[M], tức là số lượng đồng tiền ít nhất cần thiết để đổi số tiền M

Lập bảng quy hoạch

| 0 1 2 3 4 5 6 7 8 9 10 - 0 | 0 ∞ ∞ ∞ ∞ ∞ ∞ ∞ ∞ ∞ ∞ 1 | 0 1 2 3 4 5 6 7 8 9 10 2 | 0 1 1 2 2 3 3 4 4 5 5 3 | 0 1 1 1 2 2 2 3 3 3 4 5 | 0 1 1 1 2 1 2 2 3 2 3 10 | 0 1 1 1 2 1 2 2 3 2 1

Trang 31

7 Độ dài xâu con dài nhất

Duyệt qua từng ký tự trong xâu X và Y:

 Nếu X[i] bằng Y[j], tức là ta tìm thấy một ký tự mới trong xâu con chung Ta cập nhật giá trị của L[j] bằng giá trị của P[j-1]

 Ngược lại, ta cập nhật giá trị của L[j] bằng giá trị lớn nhất giữa P[j] và L[j-1]

Sau khi duyệt qua tất cả các ký tự trong X và Y, ta cập nhật mảng P bằng mảng L và tiếp tục duyệt

Kết quả cuối cùng là giá trị của L[ny], tức là độ dài của xâu con chung dài nhất Lập bảng quy hoạch

| C o n g C h i e n - 0 | 0 0 0 0 0 0 0 0 0 C 0 | 0 1 1 1 1 1 1 1 1 h 0 | 0 1 1 1 1 2 2 2 2 i 0 | 0 1 1 1 1 2 3 3 3

Trang 32

e 0 | 0 1 1 1 1 2 3 3 4 n 0 | 0 1 1 1 1 2 3 4 4 C 0 | 0 1 2 2 2 2 2 2 2 o 0 | 0 1 2 2 3 3 3 3 3 n 0 | 0 1 2 3 3 3 3 3 3 g 0 | 0 1 2 3 4 4 4 4 4

2 Kiểm tra phần tử ở giữa:

So sánh phần tử ở giữa mảng với giá trị cần tìm Nếu phần tử này trùng khớp với giá trị cần tìm, chúng ta đã tìm thấy nó và trả về chỉ số của phần tử đó

3 Chọn phần mảng để tiếp tục tìm kiếm:

Nếu phần tử ở giữa mảng lớn hơn giá trị cần tìm, chúng ta chỉ cần tìm kiếm trong nửa mảng bên trái

Trang 33

Nếu phần tử ở giữa mảng nhỏ hơn giá trị cần tìm, chúng ta chỉ cần tìm kiếm trong nửa mảng bên phải

4 Lặp lại quá trình cho đến khi tìm thấy hoặc không thể tìm thấy:

Lặp lại quá trình trên cho đến khi tìm thấy phần tử cần tìm hoặc phần tử này không tồn tại trong mảng Nếu phần tử không tồn tại, chúng ta sẽ trả về một giá trị đặc biệt để biểu thị việc không tìm thấy

5 Trả về kết quả:

Nếu tìm thấy phần tử, trả về chỉ số của nó trong mảng

Nếu không tìm thấy, trả về một giá trị đặc biệt để biểu thị việc không tìm thấy

Trang 34

2 Dãy con liên tục có tổng lớn nhất

1 Khởi tạo các biến:

max_so_far: lưu trữ tổng lớn nhất của dãy con liên tục đã tìm thấy curr_max: lưu trữ tổng tạm thời của dãy con liên tục hiện tại begin và end: lưu trữ chỉ số của dãy con liên tục có tổng lớn nhất 2 Duyệt qua mảng:

Bắt đầu từ phần tử thứ 2 của mảng, vì chúng ta đã xử lý phần tử đầu tiên ở bước khởi tạo Duyệt qua từng phần tử của mảng:

So sánh a[i] với curr_max + a[i] Nếu a[i] lớn hơn tổng tạm thời hiện tại (curr_max + a[i]), tức là bắt đầu một dãy con mới từ a[i]

Cập nhật curr_max thành giá trị lớn hơn giữa a[i] và curr_max + a[i] So sánh max_so_far với curr_max để cập nhật giá trị max_so_far nếu cần 3 Xác định dãy con liên tục có tổng lớn nhất:

Sau khi duyệt qua toàn bộ mảng, max_so_far sẽ chứa tổng lớn nhất của dãy con liên tục Sử dụng begin và end để in ra dãy con liên tục có tổng lớn nhất

4 Trả về kết quả:

Trả về giá trị max_so_far, tức là tổng lớn nhất của dãy con liên tục

Ngày đăng: 13/05/2024, 20:51

Tài liệu cùng người dùng

Tài liệu liên quan