动态规划问题之 钢条切割

来源:互联网 发布:网络脱口秀节目策划书 编辑:程序博客网 时间:2024/05/28 16:00

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

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

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

这里写图片描述

这里写图片描述

这里写图片描述

(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[n] >= 0)        return r[n];    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[n] = 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;}
原创粉丝点击