Bài tập  /  Bài đang cần trả lời

Khác - Đại học
18/06 11:55:08

Viết chương trình c++ bài toán túi

Viết chương trình c++ bài toán túi
2 trả lời
Hỏi chi tiết
Trợ lý ảo
28
Tham khảo câu trả lời từ Trợ lý ảo Lazi
Bài toán túi (Knapsack problem) là một bài toán tối ưu hóa tổ hợp cổ điển. Có nhiều biến thể của bài toán này, nhưng biến thể phổ biến nhất là bài toán túi 0/1. Trong bài toán này, bạn có một túi có sức chứa cố định và một tập hợp các vật phẩm, mỗi vật phẩm có trọng lượng và giá trị. Mục tiêu là chọn một tập hợp các vật phẩm để tối đa hóa tổng giá trị mà không vượt quá sức chứa của túi.

Dưới đây là một chương trình C++ giải quyết bài toán túi 0/1 sử dụng phương pháp quy hoạch động:

```cpp
#include
#include
#include

// Hàm giải quyết bài toán túi 0/1 bằng phương pháp quy hoạch động
int knapsack(int W, const std::vector& weights, const std::vector& values, int n) {
// Tạo bảng DP để lưu trữ giá trị tối ưu cho từng trọng lượng và số lượng vật phẩm
std::vector> dp(n + 1, std::vector(W + 1, 0));

// Duyệt qua tất cả các vật phẩm
for (int i = 1; i <= n; ++i) {
// Duyệt qua tất cả các trọng lượng từ 0 đến W
for (int w = 0; w <= W; ++w) {
if (weights[i - 1] <= w) {
// Nếu trọng lượng của vật phẩm hiện tại nhỏ hơn hoặc bằng trọng lượng hiện tại của túi
// thì chọn giá trị lớn hơn giữa việc không chọn vật phẩm này và việc chọn vật phẩm này
dp[i][w] = std::max(dp[i - 1][w], dp[i - 1][w - weights[i - 1]] + values[i - 1]);
} else {
// Nếu trọng lượng của vật phẩm hiện tại lớn hơn trọng lượng hiện tại của túi
// thì không chọn vật phẩm này
dp[i][w] = dp[i - 1][w];
}
}
}

// Giá trị tối ưu sẽ nằm ở dp[n][W]
return dp[n][W];
}

int main() {
int W; // Sức chứa của túi
int n; // Số lượng vật phẩm

std::cout << "Nhập sức chứa của túi: ";
std::cin >> W;

std::cout << "Nhập số lượng vật phẩm: ";
std::cin >> n;

std::vector weights(n);
std::vector values(n);

std::cout << "Nhập trọng lượng và giá trị của từng vật phẩm:\n";
for (int i = 0; i < n; ++i) {
std::cout << "Vật phẩm " << i + 1 << ":\n";
std::cout << "Trọng lượng: ";
std::cin >> weights[i];
std::cout << "Giá trị: ";
std::cin >> values[i];
}

int max_value = knapsack(W, weights, values, n);
std::cout << "Giá trị tối đa có thể đạt được: " << max_value << std::endl;

return 0;
}
```

Giải thích:
1. `knapsack` là hàm chính giải quyết bài toán túi 0/1 bằng phương pháp quy hoạch động.
2. `dp` là bảng lưu trữ giá trị tối ưu cho từng trọng lượng và số lượng vật phẩm.
3. Chúng ta duyệt qua tất cả các vật phẩm và trọng lượng, cập nhật bảng `dp` dựa trên việc chọn hoặc không chọn vật phẩm hiện tại.
4. Kết quả cuối cùng là giá trị tối ưu nằm ở `dp[n][W]`.

Chương trình này yêu cầu người dùng nhập sức chứa của túi, số lượng vật phẩm, trọng lượng và giá trị của từng vật phẩm, sau đó tính toán và in ra giá trị tối đa có thể đạt được.
1
0
Việt Hưng
18/06 11:57:30
+5đ tặng
#include <iostream>
using namespace std;
int max(int x, int y) {
   return (x > y) ? x : y;
}
int tromDo(long long m, int a[], int b[], int n) {
   int i, t;
   int k[n + 1][m + 1];
   for (i = 0; i <= n; i++) {
      for (t = 0; t <= m; t++) {
         if (i == 0 || t == 0)
            k[i][t] = 0;
         else if (b[i - 1] <= t)
            k[i][t] = max(a[i - 1] + k[i - 1][t - b[i - 1]], k[i - 1][t]);
         else
        k[i][t] = k[i - 1][t];
      }
   }
   return k[n][m];
}
int main() {
    freopen("DRSEM.INP","r",stdin);
    freopen("DRSEM.OUT","w",stdout);
    int n; long long m;
    cin >> n >> m;
    int a[n], b[n];
    for (int i = 0; i < n; i++) {
      cin >> a[i];
      cin >> b[i];
    }
   cout << tromDo(m, a, b, n);
   return 0;
}

Mở khóa để xem toàn bộ nội dung trả lời

(?)
Bạn đã đạt đến giới hạn của mình. Bằng cách Đăng ký tài khoản, bạn có thể xem toàn bộ nội dung trả lời
Cải thiện điểm số của bạn bằng cách đăng ký tài khoản Lazi.
Xem toàn bộ các câu trả lời, chat trực tiếp 1:1 với đội ngũ Gia sư Lazi bằng cách Đăng ký tài khoản ngay bây giờ
Tôi đã có tài khoản? Đăng nhập
1
0
Hưng vloag
18/06 12:01:23
+4đ tặng
#include
using namespace std;
int max(int x, int y) {
return (x > y) ? x : y;
}
int tromDo(long long m, int a[], int b[], int n) {
int i, t;
int k[n + 1][m + 1];
for (i = 0; i <= n; i++) {
for (t = 0; t <= m; t++) {
if (i == 0 || t == 0)
k[i][t] = 0;
else if (b[i - 1] <= t)
k[i][t] = max(a[i - 1] + k[i - 1][t - b[i - 1]], k[i - 1][t]);
else
k[i][t] = k[i - 1][t];
}
}
return k[n][m];
}
int main() {
freopen("DRSEM.INP","r",stdin);
freopen("DRSEM.OUT","w",stdout);
int n; long long m;
cin >> n >> m;
int a[n], b[n];
for (int i = 0; i < n; i++) {
cin >> a[i];
cin >> b[i];
}
cout << tromDo(m, a, b, n);
return 0;
}

Bạn hỏi - Lazi trả lời

Bạn muốn biết điều gì?

GỬI CÂU HỎI
Học tập không giới hạn cùng bạn bè học sinh cả nước, đến LAZI, sôi động, tích cực, trải nghiệm

Hôm nay bạn thế nào? Hãy nhấp vào một lựa chọn, nếu may mắn bạn sẽ được tặng 50.000 xu từ Lazi

Vui Buồn Bình thường

Học ngoại ngữ với Flashcard

×
Gia sư Lazi Gia sư
×
Trợ lý ảo Trợ lý ảo