21xrx.com
2024-12-22 21:16:36 Sunday
登录
文章检索 我的文章 写文章
C++动态规划算法的经典题目详解
2023-07-09 18:17:01 深夜i     --     --
C++ 动态规划算法 经典题目 详解

动态规划(Dynamic Programming)是一种经典的算法思想,也是计算机笔试、面试中的热门话题之一。而C++作为一门常用的编程语言,也成为了动态规划算法的常见应用之一。在本文中,我们将着重讲解一些C++动态规划算法的经典题目,并给出详细解析。

1.最长上升子序列问题

最长上升子序列问题是一种经典的动态规划问题。它的解法是:遍历整个序列,对于每个数,记录下它的前面比它值小的数字组成的最长上升子序列长度。然后用这些值递推得到结果。C++代码实现如下:

int dp[1000]; // dp数组用来存储每个数的最长上升子序列长度

int lengthOfLIS(vector & nums) {

  int n = nums.size();

  int res = 1;

  for (int i = 0; i < n; i++) {

    dp[i] = 1;

    for (int j = 0; j < i; j++) {

      if (nums[j] < nums[i]) {

        dp[i] = max(dp[i], dp[j] + 1);

      }

    }

    res = max(res, dp[i]);

  }

  return res;

}

2.最长公共子序列问题

最长公共子序列问题是指:给定两个字符串s1和s2,求它们的最长公共子序列。它的解法是:用动态规划的方法,递推出所有子序列的长度和它们的起点。最后得到最长公共子序列的长度即可。C++代码实现如下:

int dp[1000][1000]; // dp数组用来存储每个子序列的长度

int longestCommonSubsequence(string text1, string text2) {

  int n = text1.size(), m = text2.size();

  for (int i = 1; i <= n; i++) {

    for (int j = 1; j <= m; j++) {

      if (text1[i - 1] == text2[j - 1]) {

        dp[i][j] = dp[i - 1][j - 1] + 1;

      } else {

        dp[i][j] = max(dp[i - 1][j], dp[i][j - 1]);

      }

    }

  }

  return dp[n][m];

}

3.硬币找零问题

硬币找零问题是指:给定不同面额的硬币和一个总金额,写一个函数来计算最少需要的硬币个数。与上述两个问题不同的是,硬币找零问题没有与之相对应的子序列的概念。但它同样可以使用动态规划的方法解决。首先我们可以定义dp数组的含义:dp[i]表示总金额为i时,需要的最少硬币个数。然后我们可以枚举每种硬币的面额,用递推的方式得出dp数组。C++代码实现如下:

int dp[10000];

int coinChange(vector & coins, int amount) {

  memset(dp, 0x3f, sizeof(dp)); // 将dp数组初始化为INF

  dp[0] = 0; // 只需要0个硬币就可以凑出总金额为0

  for (int i = 0; i < coins.size(); i++) {

    for (int j = coins[i]; j <= amount; j++) {

      dp[j] = min(dp[j], dp[j - coins[i]] + 1);

    }

  }

  return dp[amount] == 0x3f3f3f3f ? -1 : dp[amount];

}

以上就是C++动态规划算法的几个经典题目及其详解。希望本文能对大家学习动态规划算法有所帮助。

  
  

评论区

{{item['qq_nickname']}}
()
回复
回复