此功能需要:
目标是了解通过向car1和car2添加商品可以获得的最大利润 项目不能选择两次。
public static int GetMaximumProfit(int car1_load, int car2_load, int N,
int[] loads, int[] prices, List<int> car1_items, List<int> car2_items)
{
Console.WriteLine();
int[,] dp = new int[car1_load+1, car2_load+1];
for(int i=0;i<N;i++)
{
for (int ks1=car1_load;ks1>=0;ks1--)
{
for(int ks2 = car2_load;ks2>=0;ks2--)
{
if (ks1 >= loads[i] && ks2 >= loads[i])
{
dp[ks1, ks2] = max(
dp[ks1, ks2],
dp[ks1 - loads[i], ks2] + prices[i],
dp[ks1, ks2 - loads[i]] + prices[i]
);
}
else if (ks1 >= loads[i])
{
dp[ks1, ks2] = Math.Max(
dp[ks1, ks2],
dp[ks1 - loads[i], ks2] + prices[i]
);
}
else if (ks2 >= loads[i])
{
dp[ks1, ks2] = Math.Max(
dp[ks1, ks2],
dp[ks1, ks2 - loads[i]] + prices[i]
);
}
}
}
}
cout(dp);
Console.WriteLine("Answer : " + dp[car1_load, car2_load]);
return dp[car1_load,car2_load];
}
示例:
输入:
N = 4,car1_load = 5,car2_load = 2
负载[4] = {1,2,3,5}
价格[4] = {20,10,15,25}
输出:
要插入列表中的项目是选择要在两辆车中装载的产品的索引[基于1]
利润= 45
Car1项= [2,3]
Car2物品= [1]
我的输出:
Example output of the function
我计算了最大利润。
问题是我不知道如何在dp阵列上回溯才能知道这些物品的来源。
答案 0 :(得分:1)
您应该在商品索引的数组中添加另一个维度,类似于the dynamic programming solution to the regular knapsack problem(您也许可以在没有该维度的情况下进行计算,但至少会更复杂)。
我将具体内容留给您,但这将为您提供类似的信息:
dp[i, ks1, ks2] = max(
dp[i-1, ks1, ks2],
dp[i-1, ks1 - loads[i], ks2] + prices[i],
dp[i-1, ks1, ks2 - loads[i]] + prices[i]
);
现在,您需要从头开始,并反复找出以上哪个值是最大值,然后继续该值。
只需检查左侧是否等于右侧的任何值即可。
int ks1 = car1_load, ks2 = car2_load;
for (i = N; i > 0; i--)
{
if (ks1 >= loads[i] && dp[i, ks1, ks2] == dp[i-1, ks1 - loads[i], ks2] + prices[i])
{
// Add i to car 1
ks1 -= loads[i];
}
else if (ks2 >= loads[i] && dp[i, ks1, ks2] == dp[i-1, ks1, ks2 - loads[i]] + prices[i])
{
// Add i to car 2
ks2 -= loads[i];
}
// if it's equal to dp[i-1, ks1, ks2], we don't need to do anything
}
根据您实际更改代码以将项目索引添加为数组维的方式,代码看起来可能与此有所不同。