动态规划学习(一)

  如何识别动态规划的题目

          1.提出的问题具有最优子结构性质(每一步子问题最优,导致最后得到最优解)

          2.无后效性(状态确定后,此后的值只和该状态有关。和达成的手段,路径无关)

  如何解决动态规划的题目

          1.对原问题进行分析,将原问题划分成若干子问题,一步一步来。

          2.确定每个子问题的状态。

          3.从题干中确定一些初始状态(边界状态)的值

          4.通过子问题,确认状态转移方程(从已知的出未知的方程)

          

  

  动态规划经典例题:

        

      解法一(递归+动态规划)--->由于递归会导致重复运算,所以把运算过的解都存在数组中,直接调用。节省时间

         

 1 /*
 2     求三角形顶点到底边的最大值
 3     可选择的路为正下方和右斜下方
 4     例:n=4
 5         7
 6         6 8
 7         2 1 3
 8         5 7 6 8
 9     输出: 26
10     题解:数字三角形的记忆递归型动归程序
11         由于用递归计算的话,需要重复计算很多数据,太耗时间
12         所以将计算过一次的数据存在m数组中,就可以避免重复的计算 
13 */ 
14 
15 #include<iostream>
16 #include<algorithm>
17 using namespace std;
18 #define MAX 101
19 int a[MAX][MAX];//三角形数组
20 int m[MAX][MAX];//存放指定顶点到底边的最大距离 
21 int n;//三角形的阶
22  
23 int maxsum(int x,int y)
24 {
25     if(m[x][y]!=-1)
26         return m[x][y];//最大值已经给了,可以不用计算
27     if(x==n)//到底了    
28         m[x][y]=a[x][y];     
29     else
30         {
31             int i = maxsum(x+1,y);//找出下面那个数的最大值
32             int j = maxsum(x+1,y+1);//找出右下角那个数的最大值 
33             m[x][y] = max(i,j)+a[x][y]; 
34             
35         }
36     return m[x][y];
37 }
38 
39 
40 int main()
41 {
42     int i;
43     int j;    
44     cout<<"请输入三角形的阶"<<endl;
45     cin>>n;
46     cout<<"请输入三角形的具体数据"<<endl;
47     for(i=1;i<=n;i++) 
48         for(j=1;j<=i;j++)
49         {
50             cin>>a[i][j];//具体数据
51             m[i][j]=-1; //初始化 
52         }
53     cout<<maxsum(1,1)<<endl;    
54     
55     
56     
57     
58     
59     return 0;
60 }
View Code

      

      解法二 (递推+动态规划)-->用递推的方法,从最后一行推起,由已知推出未知

 

 1 #include<iostream>
 2 #include<algorithm>
 3 using namespace std;
 4 
 5 #define Max 101
 6 int main()
 7 {
 8     int a[Max][Max];//三角形数组
 9     int n,i,j;
10     int sum[Max][Max];
11     cout<<"请输入三角形的阶"<<endl;
12     cin>>n;
13     cout<<"请输入具体数据"<<endl;
14     for(i=1;i<=n;i++)    
15         for(j=1;j<=i;j++)
16             cin>>a[i][j];
17     //初始化 
18     for(j=1;j<=n;j++)
19         sum[n][j]=a[n][j];
20     //通过递推的方法,一步一步往上加 
21     for(i=n-1;i>=1;i--)
22         for(j=1;j<=i;j++)
23             {
24                 sum[i][j]=max(sum[i+1][j],sum[i+1][j+1])+a[i][j];
25             }
26     
27     cout<<sum[1][1]<<endl;
28     
29     
30     return 0;
31 } 
View Code

    

      

          

猜你喜欢

转载自www.cnblogs.com/printwangzhe/p/12317933.html