• 动态规划入门(dp)


    dp的基本思想,是把大问题转化成一个个小问题,然后递归解决。

    所以本质思想的话还是递归。

    dp最重要的是要找到状态转移方程,也就是把大问题化解的过程。

    举个例子

    一个数字金字塔

    1       1
    2     2  3
    3   2  2  2
    4  3  1  3  3

     在上面的数字三角形中寻找一条从顶部到底边的路径,使得路径上所经过的数字之和最大。路径上的每一步都只能往左下或 右下走。只需要求出这个最大和即可,不必给出具体路径。 三角形的行数大于1小于等于100,数字为 0 - 99.

    这个题不难想到,你只要找出每一步的最大值就可以。·

    那么这么找呢?(递归啊~)

    我们先看看状态转移方程

    /*
    首先,肯定得用二维数组来存放数字三角形
    
        然后我们用D( r, j) 来表示第r行第 j 个数字(r,j从1开始算)
    
        我们用MaxSum(r, j)表示从D(r,j)到底边的各条路径中,最佳路径的数字之和。
    
        因此,此题的最终问题就变成了求 MaxSum(1,1)
    
        当我们看到这个题目的时候,首先想到的就是可以用简单的递归来解题:
    
        D(r, j)出发,下一步只能走D(r+1,j)或者D(r+1, j+1)。故对于N行的三角形,我们可以写出如下的递归式:   
    */
    if ( r == N)                  
        MaxSum(r,j) = D(r,j)    
    else        
        MaxSum( r, j) = Max{ MaxSum(r+1,j), MaxSum(r+1,j+1) } + D(r,j)   

    那么是不是就可以了?

     1 #include <iostream>    
     2 #include <algorithm>   
     3 #define MAX 101    
     4 using namespace std;   
     5 int D[MAX][MAX];    
     6 int n;    
     7 int MaxSum(int i, int j){      
     8     if(i==n)    
     9         return D[i][j];      
    10     int x = MaxSum(i+1,j);      
    11     int y = MaxSum(i+1,j+1);      
    12     return max(x,y)+D[i][j];    
    13 }  
    14 int main(){      
    15     int i,j;      
    16     cin >> n;      
    17     for(i=1;i<=n;i++)     
    18         for(j=1;j<=i;j++)          
    19             cin >> D[i][j];      
    20     cout << MaxSum(1,1) << endl;    
    21 }    

    但实际上,这个代码会超时的。

    为什么呢,

    因为已经走过的路,存在重复遍历了

    那就把已经遍历过的做一下标记,就可以避免重复遍历了。

     1 #include <iostream>    
     2 #include <algorithm>   
     3 using namespace std;  
     4    
     5 #define MAX 101  
     6     
     7 int D[MAX][MAX];      
     8 int n;    
     9 int maxSum[MAX][MAX];  
    10    
    11 int MaxSum(int i, int j){        
    12     if( maxSum[i][j] != -1 )           
    13         return maxSum[i][j];    //如果是-1那说明这个肯定不是目标,直接回去就行了    
    14     if(i==n)     
    15         maxSum[i][j] = D[i][j];       
    16     else{      
    17         int x = MaxSum(i+1,j);         
    18         int y = MaxSum(i+1,j+1);         
    19         maxSum[i][j] = max(x,y)+ D[i][j];       
    20     }       
    21     return maxSum[i][j];   
    22 }   
    23 int main(){      
    24     int i,j;      
    25     cin >> n;      
    26     for(i=1;i<=n;i++)     
    27         for(j=1;j<=i;j++) {         
    28             cin >> D[i][j];         
    29             maxSum[i][j] = -1;   //这里把所有的都设置为-1         }      
    31     cout << MaxSum(1,1) << endl;   
    32 }   
  • 相关阅读:
    lnmp环境搭建
    ffmpeg基础使用
    mongodb 副本集搭建
    二 利用pandas统计中国百亿富豪的信息
    1 mongodb安装及启动
    2 mongodb设置密码登录和创建库
    一 pandas读取excle数据
    rancher的使用
    redis主从配置
    redis安装和配置
  • 原文地址:https://www.cnblogs.com/zhmlzhml/p/12482419.html
Copyright © 2020-2023  润新知