Download as docx, pdf, or txt
Download as docx, pdf, or txt
You are on page 1of 6

TRƯỜNG ĐẠI HỌC SƯ PHẠM THÀNH PHỐ HỒ CHÍ MINH

KHOA CÔNG NGHỆ THÔNG TIN

Đề tài cuối học phần


Học phần: Phân tích & Thiết kế giải thuật

Sinh viên thực hiện : Phạm Quang Dự


Mã số sinh viên : 46.01.104.032
Mã lớp : 2121COMP140103
Giảng viên hướng dẫn: Thầy Ngô Quốc Việt

Thành phố Hồ Chí Minh, ngày 27 tháng 06 năm 2022


VẤN ĐỀ
TÌM TỔNG TÍCH LỚN NHẤT TRONG MẢNG

Cho n số nguyên, 𝑎1,𝑎2,...,𝑎𝑛. Tổng tích là tổng lớn nhất mà được thực hiện
bằng cách nhân các số kề nhau trong danh sách, sau đó cộng các tích này lại.
Quy định: một số chỉ được phép nhân tối đa một lần với lân cận của nó (hoặc
trước, hoặc sau nó).Ví dụ: cho dãy 1,2,3,1thì tổng tích cần tìm là
8=1+(2∗3)+1(số 2 chỉ được nhân một lần với số 3, và không được nhân thêm
với số1 trước nó), hoặc dãy 2,2,1,3,2,1,2,2,1,2 thì tổng tích cần tìm là
19=(2∗2)+1+(3∗2)+1+(2∗2)+1+2.Yêu cầu: thiết kế và cài đặt giải thuật quy
hoạch động để giải vấn đề trên.
PHÁT BIỂU BÀI TOÁN
Ta khởi tạo mảng hai chiều f có kích thước n*2.
Đầu tiên, xác định bài toán con:
Gọi f[i][0] là giá trị lớn nhất nếu phép toán gần nhất là cộng.
Gọi f[i][1] là giá trị lớn nhất nếu phép toán gần nhất là nhân.
Tiếp theo, xác định bài toán cơ sở:
f[0][0] = a[0] + a[1]
f[0][1] = a[0] * a[1]
Tiếp theo, xác định định đáp án của bài toán: Sau khi duyệt đến cuối a[]
thì đáp án của bài toán sẽ là giá trị lớn nhất giữa f[i][0] và f[i][1].
Cuối cùng, xác định công thức truy hồi:
f[i][0] = max(f[i - 1][0], f[i - 1][1]) + a[i + 1];
f[i][1] = (f[i - 1][0] - a[i]) + (a[i] * a[i + 1]);

Độ phức tạp của giải thuật:


f[0][0] = a[0] + a[1]; C1: 1
f[0][1] = a[0] * a[1]; C2: 1
for (int i = 1; i < n - 1; i++) { C3: n - 1
f[i][0] = max(f[i - 1][0], f[i - 1][1]) + a[i + 1]; C4: n - 1
f[i][1] = (f[i - 1][0] - a[i]) + (a[i] * a[i + 1]); C5: n - 1
}
T(n) = C1 + C2 + C3 + C4 + C5
= 1 + 1 + (n – 1) + (n – 1) + (n – 1)
= 2 + 3(n – 1)
= 2 + 3n – 3
= 3n – 1
MÃ NGUỒN VÀ HÌNH MINH HỌA
#include <bits/stdc++.h>
using namespace std;
int main() {
int n, i, sum = 0;
cin >> n;
int a[n];
int f[n][2];

for (int i = 0 ; i < n ; i++)


cin >> a[i];

for (i = 0; i < n - 1; i++) {


if (i == 0) {
f[0][0] = a[0] + a[1];
f[0][1] = a[0] * a[1];
}
else {
f[i][0] = max(f[i - 1][0] + a[i + 1], f[i - 1][1] + a[i + 1]);
f[i][1] = f[i - 1][0] - a[i] + a[i] * a[i + 1];
}
sum = max(f[i][0], f[i][1]);
}

cout << sum;


return 0;
}
Ví dụ 1:

Ví dụ 2:
TÀI LIỆU THAM KHẢO

[1] MMP.pla(2022). Retrieved 28 June 2022, from https://viblo.asia/p/cach-


tiep-can-bai-toan-quy-hoach-dong-phan-1-bWrZnoRQlxwce, "Quy hoạch
động là gì?," 31 10 2021. [Online]. Available: https://o2.edu.vn/quy-hoach-
dong-la-gi/.

You might also like