问题描述:
假设现有容量m kg的背包,另外有i个物品,重量分别为w[1] w[2] ... w[i] (kg),价值分别为p[1] p[2] ... p[i] (元),将哪些物品放入背包可以使得背包的总价值最大?最大价值是多少?(示例一:m=10 i=3 重量和价值分别为 3kg-4元 4kg-5元 5kg-6元 )
穷举法:
static void Main(string[] args)
{
int m;
//int n = 3;
int[] weight = new int[4] { 0,3, 4, 5 };
int[] price = new int[4] { 0,4, 5, 6 };
Console.WriteLine(ExhaustiveMethod(10,weight,price));
Console.WriteLine(ExhaustiveMethod(7,weight,price));
Console.WriteLine(ExhaustiveMethod(5,weight,price));
Console.WriteLine(ExhaustiveMethod(4,weight,price));
Console.WriteLine(ExhaustiveMethod(3,weight,price));
}
public static int ExhaustiveMethod(int m, int[] w, int[] p)
{
int i = w.Length-1;//物品个数
int maxPrice = 0;
for(int j = 0; j < Math.Pow(2, i); j++)
{
int tempWeight = 0;
int tempPrice = 0;
//取得二进制值
for(int number = 1; number <= i; number++)
{
int result = GetBinarySystem(j, number);
if(result == 1)
{
tempWeight += w[number];
tempPrice += p[number];
}
}
if (tempWeight <= m && tempPrice > maxPrice)
{
maxPrice = tempPrice;
}
}
return maxPrice;
}
public static int GetBinarySystem(int j,int number)
{
//取得i的第number位的二进制值,是1还是0
int A = j;
int B = (int)Math.Pow(2, number-1);
int result = A & B;
if(result == 0)
{
return 0;
}
else
{
return 1;
}
}
动态规划算法:
1.递归:
internal class Program
{
static void Main(string[] args)
{
int m;
int[] weight = new int[4] { 0, 3, 4, 5 };
int[] price = new int[4] { 0, 4, 5, 6 };
Console.WriteLine(MaxPrice(10,3, weight, price));
Console.WriteLine(MaxPrice(7,3, weight, price));
Console.WriteLine(MaxPrice(5,3, weight, price));
Console.WriteLine(MaxPrice(4,3, weight, price));
Console.WriteLine(MaxPrice(3,3, weight, price));
}
public static int MaxPrice(int m,int i, int[] w, int[] p)
{
//int i = w.Length - 1;
if (i == 0 || m == 0) return 0;
if (w[i] > m)
{
return MaxPrice(m, i-1, w, p);
}
else
{
int tempPrice1 = MaxPrice(m - w[i], i-1, w, p)+p[i];
int tempPrice2 = MaxPrice(m,i-1, w, p);
if(tempPrice1 > tempPrice2)
{
return tempPrice1;
}
else
{
return tempPrice2;
}
}
}
}
2.自顶向下带备忘录:
internal class Program
{
public static int[,] momery = new int[11, 4];
static void Main(string[] args)
{
//m背包容量,i物品个数
int m;
int[] weight = new int[4] { 0, 3, 4, 5 };
int[] price = new int[4] { 0, 4, 5, 6 };
Console.WriteLine(MaxPrice(10, 3, weight, price, momery));
Console.WriteLine(MaxPrice(7, 3, weight, price, momery));
Console.WriteLine(MaxPrice(5, 3, weight, price, momery));
Console.WriteLine(MaxPrice(4, 3, weight, price, momery));
Console.WriteLine(MaxPrice(3, 3, weight, price, momery));
}
public static int MaxPrice(int m, int i, int[] w, int[] p, int[,] momery)
{
//int i = w.Length - 1;
if (i == 0 || m == 0) return 0;
if (momery[m,i] != 0)
{
return momery[m,i];
}
if (w[i] > m)
{
momery[m,i] = MaxPrice(m, i - 1, w, p, momery);
return momery[m, i];
}
else
{
int tempPrice1 = MaxPrice(m - w[i], i - 1, w, p, momery) + p[i];
int tempPrice2 = MaxPrice(m, i - 1, w, p, momery);
if (tempPrice1 > tempPrice2)
{
momery[m,i] = tempPrice1;
}
else
{
momery[m,i] = tempPrice2;
}
return momery[m,i];
}
}
}
3.自底向上:
internal class Program
{
static void Main(string[] args)
{
int m;
int[] weight = new int[4] { 0, 3, 4, 5 };
int[] price = new int[4] { 0, 4, 5, 6 };
Console.WriteLine(MaxPrice(10, 3, weight, price));
Console.WriteLine(MaxPrice(7, 3, weight, price));
Console.WriteLine(MaxPrice(5, 3, weight, price));
Console.WriteLine(MaxPrice(4, 3, weight, price));
Console.WriteLine(MaxPrice(3, 3, weight, price));
}
public static int[,] momery = new int[11, 4];
public static int MaxPrice(int m, int i, int[] w, int[] p)
{
if (momery[m, i] != 0) return momery[m, i];
for (int tempM=1; tempM<m+1; tempM++)
{
for(int tempI=1; tempI<i+1; tempI++)
{
if (momery[tempM, tempI] != 0) continue;
if (w[tempI]>tempM)
{
momery[tempM,tempI] = momery[tempM,tempI-1];
}
else
{
int maxPrice1 = momery[tempM-w[tempI],tempI-1]+p[tempI];
int maxPrice2 = momery[tempM, tempI - 1];
if (maxPrice1 > maxPrice2)
{
momery[tempM, tempI]=maxPrice1;
}
else
{
momery[tempM, tempI] = maxPrice2;
}
}
}
}
return momery[m,i];
}
}