动态规划算法:
动态规划算法通常基于一个递推公式及一个或多个初始状态。当前子问题的解将由上一次子问题的解推出。动态规划和分治法相似,都是通过组合子问题的解来求解原问题。分治法将问题划分成互不相交的子问题,递归求解子问题,再将他们的解组合起来,求出原问题的解。与之相反,动态规划应用于子问题重叠的情况,即不同的子问题具有公共的子子问题。在这种情况下,分治算法会做出许多不必要的工作,它会反复的求解那些公共子问题。而动态规划算法对每个子子问题只求解一次,将结果保存到表格中,从而无需每次求解一个子子问题都要重新计算。
钢条切割问题:
长度 i | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
价格p[i] | 1 | 5 | 8 | 9 | 10 | 17 | 17 | 20 | 24 | 30 |
常规递归方法:
internal class Program
{
static void Main(string[] args)
{
int n = 5;//要切割的钢条长度
int[] price = { 0, 1, 5, 8, 9, 10, 17, 17, 20, 24, 30 };//数值=价格,索引=钢条长度
Console.WriteLine(MaxPrice(0,price));
Console.WriteLine(MaxPrice(1,price));
Console.WriteLine(MaxPrice(2,price));
Console.WriteLine(MaxPrice(3,price));
Console.WriteLine(MaxPrice(4,price));
Console.WriteLine(MaxPrice(5,price));
Console.WriteLine(MaxPrice(6,price));
Console.WriteLine(MaxPrice(7,price));
Console.WriteLine(MaxPrice(8,price));
Console.WriteLine(MaxPrice(9,price));
Console.WriteLine(MaxPrice(10,price));
}
public static int MaxPrice(int n, int[] p)
{
if (n == 0) return 0;
int tempMaxPrice = 0;
for(int i = 1; i < n+1; i++)
{
int maxPrice = p[i]+MaxPrice(n-i, p);
if(maxPrice > tempMaxPrice)
{
tempMaxPrice = maxPrice;
}
}
return tempMaxPrice;
}
}
动态规划-自顶向下法:
internal class Program
{
static void Main(string[] args)
{
int n = 5;//要切割的钢条长度
int[] memory = new int[11];
int[] price = { 0, 1, 5, 8, 9, 10, 17, 17, 20, 24, 30 };//数值=价格,索引=钢条长度
Console.WriteLine(MaxPrice(0, price, memory));
Console.WriteLine(MaxPrice(1, price, memory));
Console.WriteLine(MaxPrice(2, price, memory));
Console.WriteLine(MaxPrice(3, price, memory));
Console.WriteLine(MaxPrice(4, price, memory));
Console.WriteLine(MaxPrice(5, price, memory));
Console.WriteLine(MaxPrice(6, price, memory));
Console.WriteLine(MaxPrice(7, price, memory));
Console.WriteLine(MaxPrice(8, price, memory));
Console.WriteLine(MaxPrice(9, price, memory));
Console.WriteLine(MaxPrice(10, price, memory));
}
public static int MaxPrice(int n, int[] p,int[] memory)
{
if (n == 0) return 0;
if (memory[n] != 0)
{
return memory[n];
}
int tempMaxPrice = 0;
for (int i = 1; i < n + 1; i++)
{
int maxPrice = p[i] + MaxPrice(n - i, p,memory);
if (maxPrice > tempMaxPrice)
{
tempMaxPrice = maxPrice;
}
}
memory[n] = tempMaxPrice;
return tempMaxPrice;
}
}
动态规划-自底向上法:
internal class Program
{
static void Main(string[] args)
{
int[] memory = new int[11];
int[] price = { 0, 1, 5, 8, 9, 10, 17, 17, 20, 24, 30 };//数值=价格,索引=钢条长度
Console.WriteLine(MaxPrice(0, price, memory));
Console.WriteLine(MaxPrice(1, price, memory));
Console.WriteLine(MaxPrice(2, price, memory));
Console.WriteLine(MaxPrice(3, price, memory));
Console.WriteLine(MaxPrice(4, price, memory));
Console.WriteLine(MaxPrice(5, price, memory));
Console.WriteLine(MaxPrice(6, price, memory));
Console.WriteLine(MaxPrice(7, price, memory));
Console.WriteLine(MaxPrice(8, price, memory));
Console.WriteLine(MaxPrice(9, price, memory));
Console.WriteLine(MaxPrice(10, price, memory));
}
public static int MaxPrice(int n, int[] p, int[] memory)
{
for (int i = 1; i < n + 1; i++)
{
//钢条长度为i时最大收益
int tempMaxPrice = 0;
for(int j = 1; j < i+1; j++)
{
int maxPrice = p[j] + memory[i-j];
if (maxPrice > tempMaxPrice)
{
tempMaxPrice = maxPrice;
}
}
memory[i] = tempMaxPrice;
}
return memory[n];
}
}