• DFS与DP算法


    名词解释:

    DFS(Dynamic Plan):动态规划

    DFS(Depth First Search):深度优先搜索

    DFS与DP的关系

    很多情况下,dfs和dp两种解题方法的思路都是很相似的,这两种算法在一定程度上是可以互相转化的。

    想到dfs也就常常会想到dp,当然在一些特定的适用场合下除外。

    dp主要运用了预处理的思想,而dfs则是类似于白手起家,一步步探索。一般来讲,能够预处理要好些,好比战争前做好准备。

    dfs和dp都是十分重要的基础算法,在各个竞赛中都有涉及,务必精通。


    题目:

    The Triangle

    描述:

    编写一个程序,计算从顶部开始到底部某处的路径上传递的最大数字总和。 每个步骤可以向左下或右下滑动。

    输入:

    程序是从标准输入读取。 第一行包含一个整数N:三角形中的行数。 以下N行描述了三角形的数据。 三角形中的行数1<N<=100.三角形中的数字全部为整数,介于0到99之间。

    输出:

    程序是标准输出。输出最大的整数和。

     样例:

    输入:

    输出:


    DFS思路:

    自顶向下,将每种路径都走一遍。

    通过迭代计算到最后一层,记录最后一层的所有值。最后一层中的最大值即为所求。

    具体代码:

     1 #include <iostream>
     2 #include <vector>
     3 #include <algorithm>
     4 #include <functional>
     5 using namespace std;
     6 
     7 // the maximum of the triangle ordinal
     8 const int max_ordinal = 100;
     9 // the depth
    10 int num_of_rows;
    11 // save data
    12 int data[max_ordinal][max_ordinal];
    13 // save the data of the final level
    14 vector<int> ans;
    15 
    16 void dfs(int level, int sum, int column)
    17 {
    18   // avoid multi calculate
    19   int current_sum = sum+data[level][column];
    20   // save data which was in final level
    21   if(level+1 == num_of_rows)
    22   {
    23     ans.push_back(current_sum);
    24     return;
    25   }
    26   // binary tree
    27   dfs(level+1, current_sum, column);
    28   dfs(level+1, current_sum, column+1);
    29 }
    30 
    31 int main()
    32 {
    33   cin >> num_of_rows;
    34   for(int i = 0; i < num_of_rows; i++)
    35     for(int j = 0; j <= i; j++)
    36       scanf("%d", &data[i][j]);
    37 
    38   dfs(0, 0, 0);
    39   cout << "output data:" << endl;
    40 
    41   sort(ans.begin(), ans.end(), greater<int>());
    42   for(int i = 0; i < ans.size(); i++)
    43   {
    44     cout << ans[i] << "	";
    45     if(!((i+1) % 5)) cout << endl;
    46   }
    47   cout << endl;
    48 
    49   return 0;
    50 }

    DP思路:

    dfs的思路是从上到下,而dp的思路是:从第二层开始,每下去一次往回看一下并取上一层相邻两个大的那个。

    具体代码:

     1 #include <iostream>
     2 #include <algorithm>
     3 #include <functional>
     4 using namespace std;
     5 
     6 // same as DFS
     7 const int max_ordinal = 100;
     8 int num_of_rows;
     9 int data[max_ordinal][max_ordinal];
    10 // the array of the dp method
    11 int dp[max_ordinal][max_ordinal];
    12 
    13 int main()
    14 {
    15     cin >> num_of_rows;
    16     for(int i = 0; i < num_of_rows; i++)
    17         for(int j = 0; j<= i; j++)
    18             scanf("%d", &data[i][j]);
    19 
    20     // dp now
    21     dp[0][0] = data[0][0];
    22     for(int i = 1; i < num_of_rows; i++)
    23     {
    24         for(int j = 0; j <= i; j++)
    25         {
    26             if(j-1 >= 0)
    27             {
    28                 dp[i][j] = data[i][j] + max(dp[i-1][j], dp[i-1][j-1]);
    29             } else {
    30                 dp[i][j] = data[i][j] + dp[i-1][j];
    31             }
    32         }
    33     }
    34 
    35   // calling 'sort' method
    36     sort(dp[num_of_rows-1], &dp[num_of_rows-1][num_of_rows], greater<int>());
    37     for(int i = 0; i < num_of_rows; i++)
    38         cout << dp[num_of_rows-1][i] << " ";
    39     cout << endl;
    40     cout << "answer is: ";
    41     cout << dp[num_of_rows-1][0] << endl;
    42 
    43     return 0;
    44 }
  • 相关阅读:
    leetcode:Valid Parentheses(有效括号匹配)
    leetcode:Remove Nth Node From End of List (移除从尾部数的第N个节点)
    leetcode:Letter Combinations of a Phone Number(手机号码的字母组合)
    leetcode:4Sums(四个数相加的和)
    leetcode:3Sum Closest
    leetcode:3Sum (三个数的和)
    leetcode:Longest Common Prefix(取最长字符串前缀)
    php数据访问
    PHP 基础知识测试题
    面相对象设计模式
  • 原文地址:https://www.cnblogs.com/WPF-342201/p/11387640.html
Copyright © 2020-2023  润新知