5 / 4 / 1
Регистрация: 19.10.2019
Сообщений: 55
1

Минимальное количество предметов в рюкзаке, для точного соответствия заданному весу

06.01.2021, 17:38. Показов 3513. Ответов 2

Author24 — интернет-сервис помощи студентам
Здравствуйте, решал задачи с рюкзаком и наткнулся на следующую:
Код
Дано N предметов массой m1, …, mN. Ими наполняют рюкзак, который выдерживает вес не более M. Как набрать вес в точности M, используя как можно меньше предметов?

Входные данные:
Первая строка входных данных содержит натуральное число N, не превышающее 100 и натуральное число M, не превышающее 10000.
Во второй строке находится N натуральных чисел mi, не превышающих 100.

Выходные данные:
Выведите наименьшее необходимое число предметов или 0, если набрать данный вес невозможно.
В голову пришло только сделать обычный рюкзак, где вес предмета равен его цене. И потом восстанавливать ответ, для каждой вершины с весом M и находить минимальную длину ответа. Но часть тестов не проходит с WA. Мой код:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
#include<iostream>
#include<iomanip>
#include<vector>
#include<map>
#include<deque>
#include<utility>
#include<string>
#include<set>
#include<iterator>
#include<queue>
#include<cstring>
#include<stack>
#include<math.h>
#define ll long long
using namespace std;
const long long inf = (long long)1000000000000000111;
 
ll i, j, k = inf, f, n, m;
vector<ll> c, w, ans;
vector<vector<ll>> a;
 
void Way(ll i, ll j) {
    if (a[i][j] == 0) {
        return;
    }
    if (a[i - 1][j] == a[i][j]) {
        Way(i - 1, j);
    }
    else {
        Way(i - 1, j - w[i]);
        ans.push_back(i);
    }
}
 
int main() {
    cin >> n >> m;
    a.resize(n + 1, vector<ll>(m + 1, 0));
    c.resize(n + 1);
    w.resize(n + 1);
    for (i = 1; i <= n; i++) {
        cin >> w[i];
        c[i] = w[i];
    }
    for (i = 1; i <= n; i++) {
        for (j = 1; j <= m; j++) {
            a[i][j] = max(a[i - 1][j], a[i][j - 1]);
            if (w[i] <= j) {
                a[i][j] = max(a[i][j], a[i - 1][j - w[i]] + c[i]);
            }
        }
    }
    for (i = 1; i <= n; i++) {
        for (j = 1; j <= m; j++) {
            if (a[i][j] == m) {
                ans.clear();
                Way(i, j);
                f = ans.size();
                k = min(k, f);
            }
        }
    }
    if (ans.size() == 0) {
        cout << 0;
        return 0;
    }
    cout << k;
}
Заранее спасибо.
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
06.01.2021, 17:38
Ответы с готовыми решениями:

Разложить все N предметов в минимальное количество ящиков
Приветствую форумчане. Нужна помощь в реализации жадного алгоритма... Например : Суть...

Задача о рюкзаке, подсчет предметов
Уважаемые программисты, помогите, пожалуйста, с кодом. У меня есть StringGrid, пользователь...

Определить набор предметов наибольшей стоимости который можно унести в рюкзаке
Подскажите алгоритм или решение , буду очень благодарен! Дано N предметов массой m1, m2, ..., mN и...

Запрос: вывести количество предметов, по которым экзаменовался каждый студент, сдававший более 2 предметов
Напишите запрос на SQL, выводящий количество предметов, по которым экзаменовался каждый студент,...

2
817 / 504 / 211
Регистрация: 19.01.2019
Сообщений: 1,196
06.01.2021, 20:50 2
Это разновидность Subset sum problem, хоть и похожа на проблему рюкзака. Посмотрите, как выглядит код у geeksforgeeks и допилите под свои нужды. Матрицу они построили, осталось найти наименьший путь, с чем поможет bfs.
0
392 / 262 / 193
Регистрация: 02.05.2017
Сообщений: 1,003
07.01.2021, 09:22 3
Не ясно, в чем проблема хранить в a[i][j] не максимальную цену набранных предметов, как у вас сейчас в коде, а как раз наименьший размер подмножества. Вместо максимумов в 46, 48 выбирать минимумы, c[i] заменить на 1, вместо восстановления ответа вывести a[n][M]. И, если у вас сейчас рюкзак правильно написан, вроде как должно работать.
0
07.01.2021, 09:22
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
07.01.2021, 09:22
Помогаю со студенческими работами здесь

Получить список предметов, на изучение которых отведено максимальное количество часов среди всех предметов
Получить список предметов, на изучение которых отведено максимальное количество часов среди всех...

Сделать так, что бы в общем балле отображался сумма, складываемых 4 предметов и деленный на тот же количество предметов
Здравствуйте программисты! Как можно сделать так, что бы в общем балле отображался сумма,...

Из заданных семи предметов выбрать такие, чтобы их суммарный вес в рюкзаке был менее N кг, а стоимость – наибольшей.
Ввод входных данных: может быть организован как с клавиатуры, так и из текстового файла. Вывод...

Задача о рюкзаке: упаковать рюкзак так, чтобы общая ценность предметов была наибольшей и вес не превышал объем рюкзака
«ЗАДАЧА О РЮКЗАКЕ» Путешественник собрался в поход. Перед ним 5 предметов, для каждого известна...

Задача else if (По заданному весу образцов определить какой из них...)
Есть 3 образца минералов А,B,C одинакового размера.Самый легкий из них - ильменит. По заданому весу...

Определяет по заданному разбиению избирателей на группы минимальное количество сторонников партии
Здрям! Задача Тимус Вам надо написать программу, которая определяет по заданному разбиению...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
3
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru