Блог пользователя mohalllka

Автор mohalllka, история, 9 лет назад, По-русски

Доброго времени, CF! Мне не к кому обратиться, кроме как к вам и прошу помощи с решением этой задачи на ДП. Я написал решение, но как назло она не взяла только 1 тест. Мое решение на pastebin:

Решение

P.S. Тест на котором он дает неверный ответ у меня:

4 5

1 1 1 1

Я дебажил, я пытался, я понял в каком случае возникает ошибка, но исправить так и не смог.

  • Проголосовать: нравится
  • -6
  • Проголосовать: не нравится

»
9 лет назад, # |
  Проголосовать: нравится +5 Проголосовать: не нравится

У Вас неверная база динамики.

Когда Вы не рассматривали ни одного предмета, Вы не можете собрать никакую сумму, за исключением нуля (использовав 0 предметов). У Вас же получается, что можно взять ровно один предмет два раза.

  • »
    »
    9 лет назад, # ^ |
    Rev. 3   Проголосовать: нравится 0 Проголосовать: не нравится

    Я понимаю, но не совсем. Если я правильно понял вас, то знайте, я сдавал такое же решение, только:

    1) Когда вводил значения присваивал в массиве dp[arr[i]] единицу

    2) Считал до нуля не включительно

    Но все равно получалось также, как и сейчас.

    Если можно, то объясните подробнее! Спасибо.

    • »
      »
      »
      9 лет назад, # ^ |
      Rev. 3   Проголосовать: нравится +8 Проголосовать: не нравится

      То, что Вы заранее делаете dp[arr[i]] = 1 — это значит, что можно в самом начале взять один предмет, но он никуда не денется из набора доступных предметов, и его можно будет взять потом еще раз.

      Я бы Вам посоветовал вначале написать двумерную динамику: dp[i][j] — наименьшее количество предметов, которое нужно взять для того, чтобы собрать сумму j, при этом можно брать только первые i предметов. Как ни странно, то, что Вы пишете — это попытка оптимизировать потребление памяти в этой самой динамике, только вот делаете Вы это неправильно.

    • »
      »
      »
      9 лет назад, # ^ |
        Проголосовать: нравится 0 Проголосовать: не нравится

      Если сделаешь тест

      1 4    
      2   
      

      то твой код выведет ответ 2 вместо 0, как и говорил AlexanderBolshakov
      Правильно будет вот так

          for(int i=0; i<n; ++i)
          {
              for(int j=sum; j>0; --j)
              {
                  if(res[j])
                  {
                      if(res[j+arr[i]])
                      {
                          res[j+arr[i]] = min(res[j+arr[i]], 1+res[j]);//если до этого res[a[i]] был всегда 1, то теперь не всегда так будет
                      }
                      else
                      {
                          res[j+arr[i]] = res[j] + 1;//тут тоже))
                      }
                  }
              }
              res[arr[i]]=1; // если написать тут то он не будет 2 раза считать один и тот же элемент
          }
      
»
9 лет назад, # |
  Проголосовать: нравится +5 Проголосовать: не нравится

Вроде так, потести: http://paste.ubuntu.com/12896693/

  • »
    »
    9 лет назад, # ^ |
      Проголосовать: нравится 0 Проголосовать: не нравится

    не понимаю, мой код делает равносильное вашему, только у вас при вводе, и он зашел на все 51, а у меня нет