Giáo Trình Ôn Tập Các Thuật Toán Thiết Kế Cơ Bản

MỤC LỤC

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ả.

Quay lui

    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 đó. - 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.

    - 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 đó.

    - Sử dụng một mảng x[] để lưu trữ hoán vị hiện tại và một mảng b[] để đánh dấu các số đã được chọn. - Sử dụng đệ quy để thử tất cả các cách chọn số cho vị trí hiện tại trong hoán vị. - 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.

    - 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. - 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 ô hiện tại chưa có giá trị, nó sẽ thử tất cả các giá trị hợp lệ cho ô đó.

    Quy hoạch động

      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. 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.

      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.

      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. 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.

      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. 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ử trước đó. 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.

      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ó. 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.  Mảng P được khởi tạo với giá trị 0 cho tất cả các phần tử, đại diện cho xâu con chung dài nhất tính đến thời điểm trước đó.

       Mảng L được khởi tạo với giá trị 0 cho phần tử đầu tiên, đại diện cho xâu con chung dài nhất tính đến thời điểm hiện tại. 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.

      Chia để trị

        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. 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.

        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. 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. 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.

        Nếu không, tính số Fibonacci của n-1 và n-2 bằng cách đệ quy, sau đó cộng chúng lại với nhau. Tìm phần tử lớn nhất trong mảng A[] từ chỉ số low đến high với low = 0 và high = n-1 Nếu low và high trùng nhau (tức là chỉ có một phần tử trong mảng), trả về phần tử đó là phần tử lớn nhất. Ngược lại, chia mảng thành hai phần bằng cách tính chỉ số trung bình mid.

        Gọi đệ quy hàm FindMax trên hai phần tử mảng con bên trái và bên phải của mid, sau đó so sánh hai giá trị trả về. Sử dụng thuật toán Euclid, trong đó gcd(a, b) là ước số chung lớn nhất của hai số a và b. Sử dụng phương pháp chia để trị để tính lũy thừa của một số a với một số mũ n.

        Bước 2: Lặp qua các phần tử trước đó (các phần tử đã được sắp xếp) để tìm vị trí đúng cho phần tử v. Bước 3: So sánh phần tử đang xét (v) với các phần tử đứng trước trong mảng. Nếu phần tử trước đó lớn hơn v, di chuyển phần tử đó sang phải để tạo ra một vị trí trống cho v.