Почему не работает решение этой проблемы с рюкзаком? - PullRequest
0 голосов
/ 01 августа 2020

Недавно решал задачу о рюкзаке. В этой версии рюкзака вместо веса в состояние берется значение.

Проблема такая же, как и в обычном рюкзаке: имеется n предметов, элемент i имеет вес wi и значение vi. Вместимость ранца - W. Найдите максимально возможную сумму значений предметов, которые могут быть заполнены в рюкзаке.

Ограничения: 1 <= n <= 100 1 <= W <= 10 ^ 9 1 <= wi <= W 1 <= vi <= 1000 </p>

Ввод: n W w1 v1 w2 v2 w3 v3 ..... wn vn

Из-за большого значения веса, мы должны принимать значение в состоянии, и результатом будет минимальный вес. Хотя я объяснил проблему, но на случай, если вам потребуется дополнительная информация, это ссылка на проблему.

Приведенный ниже код - это моя попытка решить проблему. Я использовал индексирование на основе 1. Я не могу найти ошибку. Я пробовал отлаживать код, но это не помогло. Я застрял на этом с 2 дней. Пожалуйста, помогите.

  #include <iostream>
  #include <limits.h>
  using namespace std;

  int main()
  {
    int n,W;

    cin>>n>>W;    // no. of elements and maxm. Weight
    int v[n+1],w[n+1];   // array for value and weight 
    int dp[n+1][100001];  // dp array with size n+1 and 10^5+1 (for v max value 1000, and for n 100)

    // Initializing arrays

    v[0]=INT_MAX; w[0]=INT_MAX;

    for (int i = 0; i < n+1; ++i)
    {
      for (int j = 0; j < 100001; ++j)
      {
        dp[i][j]=INT_MAX;      
      }
    }

    for (int i = 1; i < n+1; ++i){
      cin>>w[i]>>v[i];
    }
    
    dp[1][0]=0; // for 0 value, no value for weight
    dp[1][v[1]]=w[1]; 

    
    for (int i = 2; i < n+1; ++i) 
    {
      dp[i][0]=0;
      
      for (int j = 1; j < 100001; ++j)
      {
        dp[i][j]=dp[i-1][j]; // excluding the element

        if(j-v[i]>=1){ 
          dp[i][j]=min(dp[i][j],w[i]+dp[i-1][j-v[i]]); // min of including and excluding element
        }
      }
    }

    // to find the max value for which weight is <=W
    for(int i=100000; i>=1; i--){
      if(dp[n][i]<=W){
        cout<<i; break;
      }
    }

    return 0;
  }

1 Ответ

1 голос
/ 01 августа 2020

Есть несколько проблем с вашим кодом:

  • Максимальное значение может быть 0
  • вес, необходимый для достижения некоторого значения, может быть> INT_MAX
  • dp[1][v[1]]=w[1]; необязательная строка
  • for (int j = 1; j < 100001; ++j) j из 0 допустимый вес, хотя
  • if(j-v[i]>=1){ то же, что и выше

Вот фиксированная версия:

 #include <iostream>
  #include <limits.h>
#define ll long long
  using namespace std;

  int main()
  {
    int n,W;

    cin>>n>>W;    // no. of elements and maxm. Weight
    ll v[n+1],w[n+1];   // array for value and weight 
    ll dp[n+1][100001];  // dp array with size n+1 and 10^5+1 (for v max value 1000, and for n 100)

    // Initializing arrays

    v[0]=1e17; w[0]=1e17;

    for (int i = 0; i < n+1; ++i)
    {
      for (int j = 0; j < 100001; ++j)
      {
        dp[i][j]=INT_MAX;      
      }
    }

    for (int i = 1; i < n+1; ++i){
      cin>>w[i]>>v[i];
    }
    
    dp[0][0]=0; // for 0 value, no value for weight

    for (int i = 1; i < n+1; ++i) 
    {
      dp[i][0]=0;
      
      for (int j = 0; j < 100001; ++j)
      {
        dp[i][j]=dp[i-1][j]; // excluding the element

        if(j-v[i]>=0){ 
          dp[i][j]=min(dp[i][j],w[i]+dp[i-1][j-v[i]]); // min of including and excluding element
        }
      }
    }

    // to find the max value for which weight is <=W
    for(int i=100000; i>=0; i--){
      if(dp[n][i]<=W){
        cout<<i; break;
      }
    }

    return 0;
  }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...