算法1:动态规划

动态规划是很重要的算法。

       动态规划的基本思想是:将求解的问题分解成若干个子问题,先求解子问题,然后再从这些子问题的解得到原问题的解。与分治法的区别是,适合用动态规划解决的问题,经分解得到的子问题往往不是相互独立的。动态规划将问题分解成子问题,但是子问题不相互独立,而是彼此依赖,相互提供帮助,很好的利用了子问题的结构信息。

动态规划的步骤是:

1.找出最优解的特征,并刻画其结构特征;

2.递归地定义最优值;

3.以自底向上的方式计算出最优值;

4.根据计算最优值的时得到的信息,构造最优解。

动态规划算法的有效性依赖于两个最重要的性质:最优子结构性质和重叠子问题性质。

下面举一个栗子,矩阵连乘问题。

 1 //动态规划——矩阵连乘问题
 2 #include<iostream>
 3 #include<cstring> 
 4 
 5 using namespace std;
 6 int p[7]={30,35,15,5,10,20,25};//6个矩阵
 7 int m[6][6];//存放计算量的矩阵
 8 int s[6][6];//存放分割点的矩阵
 9 
10 void matrixChain()//第三步:计算最优值(前面两步没法再代码中体现,是构思的过程)
11                   //生成断点矩阵的函数,计算出最优值,返回s矩阵
12 {
13     int length=6;
14     memset(m,0,sizeof(m));
15     memset(s,0,sizeof(s));
16     for(int r=2;r<=length;r++)//r表示的是计算的范围,开始只计算两个矩阵的计算量,然后依次计算3个,4个一直到目标的6个
17                               //这是动态规划自底向上的体现,从最小的单位开始计算
18     {
19         for(int i=1;i<=length-r+1;i++)//i,j分别表示当前所计算的范围
20         {
21             int j=i+r-1;
22             m[i][j]=m[i][i]+m[i+1][j]+p[i]*p[i-1]*p[j];//因为后面要求最优值,所以这里其实是随便求一个值
23             s[i][j]=i;
24             for(int k=i+1;k<j;k++)//范围内优化,找到最小的值
25             {
26                 int temp=m[i][k]+m[k+1][j]+p[i-1]*p[k]*p[j];
27                 if(temp<m[i][j])
28                 {
29                     m[i][j]=temp;
30                     s[i][j]=k;
31                 }
32             }
33         }
34     }
35 }
36 void TraceBack(int i,int j)//第4步:构造最优解。输入s矩阵和想要求解的范围,输出最佳的括号方案
37 {
38     if(i==j)
39     {
40         cout<<"M"<<"["<<i<<"]";
41         return;
42     }
43     cout<<"(";
44     TraceBack(i,s[i][j]);
45     TraceBack(s[i][j]+1,j);
46     cout<<")";
47 }
48 int main()
49 {
50     matrixChain();
51     TraceBack(1,6);
52     cout<<m[1][6]<<endl;
53     return 0;
54 }

猜你喜欢

转载自www.cnblogs.com/neverland0718/p/11348868.html
今日推荐