Что не так в этом повторении?
Постановка задачи:
Однажды Blue Mary идет в ближайший супермаркет, чтобы купить некоторые товары. У нее есть рюкзак, емкость которого V-Max. Она находит, что на рынке есть много товаров, каждый из которых имеет объем Vi(он всегда будет кратен 10 и менее 10000) и значение Ci(1<= Ci <=5). Поскольку у нее почти неограниченные деньги, единственной проблемой, которую она должна решить, является выбор товаров таким образом, чтобы общий объем не превышал вместимость рюкзака, а сумма произведения объема и важности каждого товара была максимальной., Чтобы быть отличной математикой, она быстро придумает ответ, и теперь она хочет, чтобы вы выполнили более сложную задачу. Существует два вида товаров: основные товары и вложения. Если вы хотите купить вложение, вы должны купить его основной товар раньше.
вход
Несколько тестовых наборов, количество которых указано в самой первой строке.
Для каждого теста:
Первая строка содержит два разделенных пробелом целых числа V-Max (1<=V-Max<=32000) и номер товара N (1<=N<=60). Далее следуют N строк, каждая из которых содержит три разделенных пробелом целых числа Vi, Ci и целое число u. Если u не 0, этот товар является вложением хорошего u(как порядок во входном файле).
Чтобы сделать задачу не слишком сложной, Голубая Мария говорит вам, что:
(A) Вложение не будет иметь вложений, которые ему принадлежат.
(B) У основного блага всегда будет менее 3 вложений.
Выход
Для каждого теста:
Первая и единственная строка содержит одно целое число, обозначающее ответ.
пример
Ввод: 1 1000 5 800 2 0 400 5 1 300 5 1 400 3 0 500 2 0
Выход: 2200
Мое решение для возврата:
#include <iostream>
#include <map>
#include <tuple>
using namespace std;
multimap<int,pair<int,int>>data; //to store attachments
int wt[61],val[61];//to store main goods
int solve(int n,int vol){
if(n<1||vol<0||wt[n]>vol)
return 0;
if(wt[n]==-1)
return solve(n-1,vol);
int w = wt[n], v = val[n];
int ret = solve(n-1,vol-w)+w*v;
auto range = data.equal_range(n); //check if there are any attachments
int coun = v*w,cw = w;
for(auto i=range.first;i!=range.second;i++){
int w1 = i->second.first,v1= i->second.second;
coun+=w1*v1;
cw += w1;
ret = max(ret,solve(n-1,vol-w-w1)+w*v+w1*v1); //take only this attachment
ret = max(ret,solve(n-1,vol-cw)+coun); //take this attachment along with previous one *there can be only 2 attachments at max*
}
return ret;
}
int main ()
{
int t;
cin>>t;
while(t--){
int vmax,n;
cin>>vmax>>n;
int a,b,c;
int sz = 1;
for(int i=1;i<=n;i++){
cin>>a>>b>>c;
if(c==0){ //treat this as a main good
wt[i] = a;
val[i]=b;
}else{ //treat this as an attachment
data.insert(make_pair(c,make_pair(a,b)));
wt[i] = -1; //this indicates that this index is an attachment
}
}
cout << solve(n,vmax) << endl;
}
}
Объяснение:
Подробности об основных товарах хранятся в массивах (wt[] и val[]), а вложения хранятся в multimap<int,pair<int,int>>data
, Если wt[i] == -1, это означает, что нет основного товара по индексу i. В функции solve() эти случаи проверяются:
- Просто возьмите главное благо без всякой привязанности.
- проверить вложения
- Возьмите первое вложение вместе с основным товаром (общий вес = вес основного товара + вложение. Стоимость = стоимость основного товара + вложение)
возьмите второе вложение вдоль основного блага
возьмите оба вложения (примечание: может быть максимум 2 вложения. Если это не так, код не будет работать должным образом)
Я проверил этот код в различных тестовых случаях и он работает нормально, но при отправке я получаю сообщение об ошибке "Неправильный ответ". Обратите внимание, что это решение для возврата, и я не запомнил код. Что не так с этим решением и как я могу это исправить?