phân tích thuật toán

You might also like

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

Bài toán : cho n gói kẹo , mỗi gói kẹo có m chiếc .

Chia số kẹo thành hai


phần sao cho không phải phá bỏ các túi mà số lượng kẹo của hai phần
chênh lệch là ít nhất .

Phân tích bài toán :


- Xây dựng một bảng hai chiều ‘dp’ với số hàng là số gói kẹo và số
cột là tổng số kẹo. Giá trị dp[i][j] sẽ đại diện cho tổng số kẹo lớn
nhất có thể đạt được khi chỉ xét i gói kẹo đầu tiên và tổng số kẹo
trong phần đó không vượt quá j.
- Để tính giá trị dp[i][j], ta có thể xét từng gói kẹo thứ i. Có hai
trường hợp xảy ra:
+ Trường hợp không lấy gói kẹo thứ i: Ta sẽ có dp[i][j] = dp[i-1][j],
tức là giá trị tối ưu không thay đổi.
+ Trường hợp lấy gói kẹo thứ i: Ta sẽ có dp[i][j] = keo[i-1] + dp[i-1]
[j-keo[i-1]], tức là tổng số kẹo lớn nhất có thể đạt được là tổng số
kẹo trong gói thứ i cộng với giá trị tối ưu của bài toán con với i-1
gói kẹo và tổng số kẹo giảm đi keo[i-1].\
- Sau khi tính toán xong giá trị dp cho tất cả các trạng thái, ta có thể
xác định giá trị tối ưu cho bài toán ban đầu. Độ chênh lệch tổng số
kẹo giữa hai phần là totalSum - 2 * dp[N][totalSum/2], trong đó
totalSum là tổng số kẹo trong tất cả các gói, N là số lượng gói kẹo.
Cài đặt :
#include <iostream>
#include <vector>
#include <cmath>

using namespace std;


// Hàm trả về độ chênh lệch tổng số kẹo ít nhất giữa hai phần
int chiaKeo(vector<int>& keo) {
int N = keo.size();
int totalSum = 0; // Tổng số kẹo trong tất cả các gói
for (int i = 0; i < N; i++) {
totalSum += keo[i];
}

// Tạo bảng lưu trữ kết quả


vector<vector<int> > dp(N+1, vector<int>(totalSum+1, 0));

// Xây dựng bảng quy hoạch động


for (int i = 1; i <= N; i++) {
for (int j = 1; j <= totalSum; j++) {
// Trường hợp không lấy gói kẹo i
dp[i][j] = dp[i-1][j];
// Trường hợp lấy gói kẹo i
if (keo[i-1] <= j) {
dp[i][j] = max(dp[i][j], keo[i-1] + dp[i-1][j - keo[i-1]]);
}
}
}

int minDiff = totalSum - 2 * dp[N][totalSum/2];

return minDiff;
}

int main() {
int N; // Số lượng gói kẹo
cout << "Nhập số lượng gói kẹo: ";
cin >> N;

vector<int> keo(N);

// Nhập số lượng kẹo trong mỗi gói


for (int i = 0; i < N; i++) {
cout << "Nhập số lượng kẹo trong gói thứ " << i+1 << ": ";
cin >> keo[i];
}

int minDiff = chiaKeo(keo);


cout << "Độ chênh lệch tổng số kẹo ít nhất giữa hai phần là: " <<
minDiff << endl;

return 0;
}
Độ phức tạp thuật toán :
- O(n * total_candies).
+ Với số lượng kẹo(n) .
+ Tổng số kẹo trong tất cả các gói (total candies) .
Chạy thử :

You might also like