首页 > 其他分享 >动态规划问题

动态规划问题

时间:2024-09-11 13:52:37浏览次数:3  
标签:include nums int MAX 问题 grid 动态 规划 dp

1. 最长回文子串(LeetCode 5) 

问题描述:

给定一个字符串,找出最长的回文子串。

解题思路:

使用动态规划建立一个二维表格dp[i][j],表示子串S[i:j+1]是否为回文串。根据dp[i][j]的值来决定dp[i][j+1]的值。

#include <stdio.h>
#include <string.h>
#include <stdbool.h>

// 检查字符串s[i:j+1]是否为回文串
bool isPalindrome(char *s, int i, int j) {
    while (i < j) {
        if (s[i] != s[j]) return false;
        i++;
        j--;
    }
    return true;
}

// 动态规划求解最长回文子串
char* longestPalindrome(char* s) {
    int len = strlen(s);
    if (len == 0) return "";

    int dp[len][len];
    memset(dp, 0, sizeof(dp));

    int start = 0; // 记录最长回文子串的起始位置
    int maxLength = 1; // 记录最长回文子串的长度

    // 单字符回文串
    for (int i = 0; i < len; i++) {
        dp[i][i] = 1;
    }

    // 双字符回文串
    for (int i = 0; i < len - 1; i++) {
        if (s[i] == s[i + 1]) {
            dp[i][i + 1] = 1;
            start = i;
            maxLength = 2;
        }
    }

    // 长于2个字符的回文串
    for (int length = 3; length <= len; length++) {
        for (int i = 0; i < len - length + 1; i++) {
            int j = i + length - 1;
            if (s[i] == s[j] && dp[i + 1][j - 1]) {
                dp[i][j] = 1;
                start = i;
                maxLength = length;
            }
        }
    }

    char* result = (char*)malloc((maxLength + 1) * sizeof(char));
    strncpy(result, s + start, maxLength);
    result[maxLength] = '\0';
    return result;
}

int main() {
    char s[] = "babad";
    char* result = longestPalindrome(s);
    printf("Longest Palindromic Substring: %s\n", result);
    free(result);
    return 0;
}

 2. 编辑距离(牛客网)

问题描述:

给定两个字符串,求将一个字符串转换成另一个字符串所需的最少操作数(插入、删除、替换)。

解题思路:

使用二维动态规划表格dp[i][j],表示word1[0:i-1]word2[0:j-1]的编辑距离。根据插入、删除、替换操作更新dp[i][j]

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

// 动态规划求解编辑距离
int minDistance(char* word1, char* word2) {
    int m = strlen(word1);
    int n = strlen(word2);
    int dp[m + 1][n + 1];

    for (int i = 0; i <= m; i++) {
        for (int j = 0; j <= n; j++) {
            if (i == 0) {
                dp[i][j] = j;
            } else if (j == 0) {
                dp[i][j] = i;
            } else {
                int cost = (word1[i - 1] == word2[j - 1]) ? 0 : 1;
                dp[i][j] = fmin(fmin(dp[i - 1][j] + 1, dp[i][j - 1] + 1), dp[i - 1][j - 1] + cost);
            }
        }
    }

    return dp[m][n];
}

int main() {
    char word1[] = "intention";
    char word2[] = "execution";
    printf("Edit Distance: %d\n", minDistance(word1, word2));
    return 0;
}

 3. 最大子数组和(牛客网)

问题描述:

给定一个整数数组,找出具有最大和的连续子数组。

解题思路:

使用一维动态规划数组dp,其中dp[i]表示以第i个元素结尾的最大子数组和。递推关系为dp[i] = max(dp[i-1] + nums[i], nums[i])

#include <stdio.h>
#include <limits.h>

// 动态规划求解最大子数组和
int maxSubArray(int* nums, int numsSize) {
    int maxSum = nums[0];
    int currentSum = nums[0];

    for (int i = 1; i < numsSize; i++) {
        currentSum = fmax(nums[i], currentSum + nums[i]);
        maxSum = fmax(maxSum, currentSum);
    }

    return maxSum;
}

int main() {
    int nums[] = {-2, 1, -3, 4, -1, 2, 1, -5, 4};
    int size = sizeof(nums) / sizeof(nums[0]);
    printf("Maximum Subarray Sum: %d\n", maxSubArray(nums, size));
    return 0;
}

4. 最长递增子序列(牛客网)

问题描述:

给定一个整数数组,找到其中最长递增子序列的长度。

解题思路:

使用一维动态规划数组dp,其中dp[i]表示以第i个元素结尾的最长递增子序列的长度。递推关系为dp[i] = max(dp[j] + 1),其中j < inums[j] < nums[i]

#include <stdio.h>
#include <limits.h>

// 动态规划求解最长递增子序列
int lengthOfLIS(int* nums, int numsSize) {
    if (numsSize == 0) return 0;

    int dp[numsSize];
    int length = 1;
    dp[0] = 1;

    for (int i = 1; i < numsSize; i++) {
        dp[i] = 1;
        for (int j = 0; j < i; j++) {
            if (nums[i] > nums[j] && dp[i] < dp[j] + 1) {
                dp[i] = dp[j] + 1;
            }
        }
        if (length < dp[i]) {
            length = dp[i];
        }
    }

    return length;
}

int main() {
    int nums[] = {10, 9, 2, 5, 3, 7, 101, 18};
    int size = sizeof(nums) / sizeof(nums[0]);
    printf("Length of Longest Increasing Subsequence: %d\n", lengthOfLIS(nums, size));
    return 0;
}

 5. 0-1 胶囊问题(牛客网)

问题描述:

给定一个背包的容量和一组物品的重量及价值,求最大总价值。

解题思路:

使用二维动态规划表格dp[i][w],表示前i个物品中背包容量为w时的最大价值。递推关系为dp[i][w] = max(dp[i-1][w], dp[i-1][w-weight[i]] + value[i])

#include <stdio.h>
#include <string.h>
#include <algorithm>

#define MAX_ITEMS 100
#define MAX_CAPACITY 100

// 动态规划求解0-1背包问题
int knapsack(int weight[], int value[], int n, int capacity) {
    int dp[MAX_ITEMS][MAX_CAPACITY] = {0};

    for (int i = 1; i <= n; i++) {
        for (int w = 0; w <= capacity; w++) {
            if (weight[i-1] <= w) {
                dp[i][w] = std::max(dp[i-1][w], dp[i-1][w-weight[i-1]] + value[i-1]);
            } else {
                dp[i][w] = dp[i-1][w];
            }
        }
    }
    return dp[n][capacity];
}

int main() {
    int weight[] = {1, 2, 3};
    int value[] = {60, 100, 120};
    int n = sizeof(weight) / sizeof(weight[0]);
    int capacity = 5;

    printf("Maximum value in Knapsack = %d\n", knapsack(weight, value, n, capacity));
    return 0;
}

 6. 矩阵的最小路径和(牛客网)

问题描述

给定一个二维矩阵 grid,每个格子里有一个非负整数。你需要从矩阵的左上角 (0,0) 开始,移动到右下角 (m-1,n-1),每次只能向右或向下移动一步,计算从左上角到右下角的最小路径和。

输入

  • 一个 m x n 的二维矩阵 grid,其中 grid[i][j] 表示第 i 行第 j 列的格子的值。

输出

  • 从左上角到右下角的最小路径和。

示例

输入:

[
 [1, 3, 1],
 [1, 5, 1],
 [4, 2, 1]
]

 

输出:

7

解释:

最优路径是:1 → 3 → 1 → 1 → 1,总路径和为 7。

解题思路

这个问题可以使用动态规划(DP)解决。定义一个二维数组 dp,其中 dp[i][j] 表示从起点到 (i, j) 的最小路径和。状态转移方程如下:

  • 如果只考虑从上方和左方的移动:
    • dp[i][j] = grid[i][j] + min(dp[i-1][j], dp[i][j-1])

其中 dp[i-1][j] 是从上方来的路径和,dp[i][j-1] 是从左方来的路径和。

#include <stdio.h>
#include <limits.h>

#define MAX_ROWS 100
#define MAX_COLS 100

// 动态规划求解矩阵的最小路径和
int minPathSum(int grid[MAX_ROWS][MAX_COLS], int m, int n) {
    int dp[MAX_ROWS][MAX_COLS];

    dp[0][0] = grid[0][0];
    for (int i = 1; i < m; i++) {
        dp[i][0] = dp[i-1][0] + grid[i][0];
    }
    for (int j = 1; j < n; j++) {
        dp[0][j] = dp[0][j-1] + grid[0][j];
    }
    for (int i = 1; i < m; i++) {
        for (int j = 1; j < n; j++) {
            dp[i][j] = grid[i][j] + (dp[i-1][j] < dp[i][j-1] ? dp[i-1][j] : dp[i][j-1]);
        }
    }

    return dp[m-1][n-1];
}

int main() {
    int grid[MAX_ROWS][MAX_COLS] = {
        {1, 3, 1},
        {1, 5, 1},
        {4, 2, 1}
    };
    int m = 3, n = 3;

    printf("Minimum Path Sum: %d\n", minPathSum(grid, m, n));
    return 0;
}

标签:include,nums,int,MAX,问题,grid,动态,规划,dp
From: https://blog.csdn.net/2301_80950699/article/details/142132238

相关文章

  • 有关Latch借timing问题讲解
      之前我们提到过clockgate通过加latch的方法,解决掉不少问题。其中,也提到过,latch相对于触发器来说,其可以借timing。本文主要讲解一下latch是怎么借timing的,以及其劣势。    如图1所示,中间一个是高电平触发latch。图2所示为setup/holdcheck,绿色是holdcheck,红色是......
  • rsync 学习笔记(二)常见问题集锦
     问题一@ERROR:chrootfailedrsyncerror:errorstartingclient-serverprotocol(code5)atmain.c(1522)[receiver=3.0.3]原因服务器端的目录不存在或无权限。创建目录并修正权限可解决问题。问题二@ERROR:authfailedonmoduleteersyncerror:errorstarting......
  • ubuntu VMware Tools 无效问题
    VMwareTools与ubuntu自带的 open-vm-tools有冲突,选择其中一个安装就行了1.重新安装一下VMwareTools记录一下安装过程:点击虚拟机-重新安装VmwareTools选项,此时,会发现虚拟机设备下多了VMwareTools这一项。打开它,其里面有一个VMwareTools…tar.gz文件,我们把......
  • 【04】深度学习——训练的常见问题 | 过拟合欠拟合应对策略 | 过拟合欠拟合示例 | 正
    深度学习1.常见的分类问题1.1模型架构设计1.2万能近似定理1.3宽度or深度1.4过拟合问题1.5欠拟合问题1.6相互关系2.过拟合欠拟合应对策略2.1问题的本源2.2数据集大小的选择2.3数据增广2.4使用验证集2.5模型选择2.6K折交叉验证2.7提前终止3.过拟合欠拟合示例3.1导入库3.2......
  • 图与网络——最短路问题精解
    最短路问题(ShortestPathProblem)是图论中的一个经典问题,广泛应用于现实世界中的多个领域。该问题的核心在于如何在一个图中找到给定起点和终点之间路径权重最小的路径。路径权重通常代表时间、成本、距离等因素,因此最短路问题不仅具有理论上的研究价值,还在实际问题的解决中发挥了......
  • ThreadLocal线程重用时带来的问题
    背景我们都知道ThreadLocal实现了资源在线程内独享,线程之间隔离。实际使用中,ThreadLocal适用于变量在线程间隔离,而在方法或类间共享的场景。比如用户信息,当用户信息需要在多个方法之间传递或者共享使用的时候,同时,每个Tomcat请求的用户信息是私有的。这时可使用ThreadLocal,即直接......
  • NOIP 2018 普及组初赛试题及解析(第二部分:问题求解(1-2))
    分享代码:#include<iostream>usingnamespacestd;//函数用于检查一个数是否包含数字8boolcontainsEight(intnum){while(num>0){if(num%10==8)returntrue;//如果当前个位数是8,则返回truenum/=10;//去掉当前......
  • 后端面试经典问题汇总
    后端面试经典问题汇总后端开发在现代互联网应用中扮演着关键角色,涉及的数据处理、业务逻辑和系统性能等方面在面试中常常会被深入考察。本文将总结一些后端面试中常见的经典问题,并给出简单的解答思路。1.HTTP协议问题:请解释HTTP的工作原理和状态码?HTTP(超文本传输协......
  • 终于有人说清楚了基于大模型的Agent进行任务规划的10种方式(附代码和论文)
    在OpenAIAI应用研究主管LilianWeng的博客**《大语言模型(LLM)支持的自主式代理》**[1]中,将规划能力视为关键的组件之一,用于将任务拆解为更小可管理的子任务,这对有效可控的处理好更复杂的任务效果显著。基于大语言模型(LLM)的自主代理组成人是如何做事的?在日常工作中,我......
  • 《技术规划与路标开发实践》(深圳2024年10月11-12日)
    【课程背景】技术规划流程TPP(TechnologyPlanningProcess),就是根据业务和市场目标进行所需技术的识别和分析,并给出相应的策略的过程。技术规划的根本目标是让产品在市场竞争中取得成功。技术规划给出如何通过技术领先在未来的产品和服务的市场竞争中赢得先机或占据有利态势战略和......