您的位置:首页 > 其它

动态规划问题之 钢条切割

2017-06-09 17:47 316 查看

动态规划与分治算法异同:

分治算法将问题划分为互不相交的子问题,递归的求解子问题。分治算法会做出许多不必要的工作,会反复求解那些公共子问题。而动态规划对子问题只求解一次,将其存储在一个表格里面,无需每次都重新计算。

动态规划通常用来求解最优化问题,这个问题可能有许多可行解,每个解都有一个值,我们希望寻找具有最优值的解。我们称这样的解为问题的一个最优解,而不是最优解,因为可能有多个解达到最优值。







(1)根据书中思路,我们可以设计一套递归算法来求解,但此种解法效率会很低,原因是函数会反复递归调用自己,T(N)=2^N;

价格表在上图中:



#include<iostream>
using namespace std;

int CUT_ROD(int n[], int); //定义递归函数参数是价格数组和钢管长度
int main()
{
int p[11];
cout << "请输入价格表:";
for (int i = 1; i <= 10; i++)
{
cin >> p[i];
}                              //输入价格表格
int k; //输入钢管长度 k
cout << "请输入钢管长度:";
cin >> k;
int m = CUT_ROD(p,k);
cout << m;
system("pause");
}
int max(int a,int b)//定义max函数
{
return a?b : a > b;
}
int CUT_ROD(int p[],int n)
{
int q = -10000;
if (n == 0)
return 0;
for (int i = 1; i <= n; i++)
{
q = max(q,p[i] + CUT_ROD(p, n - i));//左边切割为i,右边递归不停的进行切割取最大值。

}

return q;

}


(2)使用动态规划法求解,动态规划会仔细安排求解顺序,牺牲一部分空间换取时间上的大幅度节省。自顶向下方法:



#include<iostream>
using namespace std;

int CUT_ROD(int n[], int,int[]); //定义递归函数参数是价格数组和钢管长度
int main()
{
int p[11];  //存储价格的数组从标1开始。
int r[11];  //存储子问题的最优解
for (int i = 0; i++; i < 11)
{
r[i] = -100000;  //初始化为负值
}

cout << "请输入价格表:";
for (int i = 1; i <= 10; i++)
{
cin >> p[i];
}                              //输入价格表格
int k; //输入钢管长度 k
cout << "请输入钢管长度:";
cin >> k;
int m = CUT_ROD(p, k,r);
cout << m;
system("pause");
}
int max(int a, int b)  //定义max函数
{
return a ? b : a > b;
}
int CUT_ROD(int p[], int n,int r[])
{
int q;
if (r
>= 0)
return r
;
if (n == 0)
q = 0;
else q = -1000;

for (int i = 1; i <= n; i++)
{
q = max(q, p[i] + CUT_ROD(p, n - i,r)); //利用已知的最优解来求大范围的最优解。

}
r
= q;

return q;

}


(3)使用自底向上方法



#include<iostream>
using namespace std;

int CUT_ROD(int n[], int); //定义递归函数参数是价格数组和钢管长度
int main()
{
int p[11];  //存储价格的数组从标1开始。

cout << "请输入价格表:";
for (int i = 1; i <= 10; i++)
{
cin >> p[i];
}                              //输入价格表格
int k; //输入钢管长度 k
cout << "请输入钢管长度:";
cin >> k;
int m = CUT_ROD(p, k );
cout << m;
system("pause");
}
int max(int a, int b)  //定义max函数
{
return a ? b : a > b;
}
int CUT_ROD(int p[], int n)
{
int q=-1000;
int r[11] ;
r[0] = 0;
int j;
for ( j = 1; j <= n; j++)
{
q = -10000;
for (int i = 1; i <=j; i++)
{
q = max(q, p[i] + r[j - i]); //利用已知的最优解来求大范围的最优解。
}

}
r[j] = q;

return q;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  动态规划