面试题答案
一键面试解题思路
- 动态规划方法:0 - 1 背包问题可以使用动态规划来解决。动态规划的核心思想是将一个大问题分解为多个小问题,并保存小问题的解,避免重复计算。
- 状态定义:我们定义一个二维数组
dp
,dp[i][j]
表示在前i
个物品中,背包容量为j
时能获得的最大价值。 - 状态转移方程:
- 对于每个物品
i
和背包容量j
,如果物品i
的重量weights[i]
大于背包容量j
,那么dp[i][j] = dp[i - 1][j]
,即不选择物品i
。 - 如果物品
i
的重量weights[i]
小于等于背包容量j
,那么dp[i][j] = Math.Max(dp[i - 1][j], dp[i - 1][j - weights[i]] + values[i])
,即在选择和不选择物品i
之间取较大值。
- 对于每个物品
- 剪枝操作:在遍历物品和背包容量时,可以提前判断一些不可能产生更优解的情况,减少不必要的计算。例如,如果剩余物品的总重量小于背包剩余容量,那么可以直接将剩余物品全部放入背包。
C# 代码实现
using System;
public class KnapsackProblem
{
public static int SolveKnapsack(int[] weights, int[] values, int capacity)
{
int n = weights.Length;
int[,] dp = new int[n + 1, capacity + 1];
for (int i = 1; i <= n; i++)
{
for (int j = 1; j <= capacity; j++)
{
if (weights[i - 1] > j)
{
dp[i, j] = dp[i - 1, j];
}
else
{
dp[i, j] = Math.Max(dp[i - 1, j], dp[i - 1, j - weights[i - 1]] + values[i - 1]);
}
}
}
return dp[n, capacity];
}
}
你可以使用以下方式调用这个方法:
class Program
{
static void Main()
{
int[] weights = { 2, 3, 4, 5 };
int[] values = { 3, 4, 5, 6 };
int capacity = 8;
int result = KnapsackProblem.SolveKnapsack(weights, values, capacity);
Console.WriteLine($"最大价值为: {result}");
}
}