@ 代码随想录算法训练营第8周(C语言)|Day57(动态规划)
Day53、动态规划(● 1143.最长公共子序列 ● 1035.不相交的线 ● 53. 最大子序和 动态规划 )
1143.最长公共子序列
题目描述
给定两个字符串 text1 和 text2,返回这两个字符串的最长公共子序列的长度。
一个字符串的 子序列 是指这样一个新的字符串:它是由原字符串在不改变字符的相对顺序的情况下删除某些字符(也可以不删除任何字符)后组成的新字符串。
例如,"ace" 是 "abcde" 的子序列,但 "aec" 不是 "abcde" 的子序列。两个字符串的「公共子序列」是这两个字符串所共同拥有的子序列。
题目解答
c
int longestCommonSubsequence(char* text1, char* text2) {
int s1=strlen(text1);
int s2=strlen(text2);
int dp[s1+1][s2+1];
memset(dp,0,sizeof(dp));
for(int i=1;i<=s1;i++){
for(int j=1;j<=s2;j++){
if(text1[i-1]==text2[j-1]){
dp[i][j]=dp[i-1][j-1]+1;
}else{
dp[i][j]=fmax(dp[i-1][j],dp[i][j-1]);
}
}
}
return dp[s1][s2];
}
题目总结
dp[i][j]:长度为[0, i - 1]的字符串text1与长度为[0, j - 1]的字符串text2的最长公共子序列为dp[i][j]。
1035.不相交的线
题目描述
我们在两条独立的水平线上按给定的顺序写下 A 和 B 中的整数。
现在,我们可以绘制一些连接两个数字 A[i] 和 B[j] 的直线,只要 A[i] == B[j],且我们绘制的直线不与任何其他连线(非水平线)相交。
以这种方法绘制线条,并返回我们可以绘制的最大连线数。
题目解答
c
int maxUncrossedLines(int* nums1, int nums1Size, int* nums2, int nums2Size) {
int dp[nums1Size+1][nums2Size+1];
memset(dp,0,sizeof(dp));
for(int i=1;i<nums1Size+1;i++){
for(int j=1;j<nums2Size+1;j++){
if(nums1[i-1]==nums2[j-1]){
dp[i][j]=dp[i-1][j-1]+1;
}else{
dp[i][j]=fmax(dp[i-1][j],dp[i][j-1]);
}
}
}
return dp[nums1Size][nums2Size];
}
题目总结
与上题一致。
53. 最大子序和
题目描述
给定一个整数数组 nums ,找到一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。
题目解答
c
int max(int a,int b){
return a>b?a:b;
}
int maxSubArray(int* nums, int numsSize) {
int dp[numsSize];
dp[0]=nums[0];
int res=nums[0];
for(int i=1;i<numsSize;i++){
dp[i]=max(dp[i-1]+nums[i],nums[i]);
res=max(res,dp[i]);
}
return res;
}
题目总结
dp[i]:包括下标i(以nums[i]为结尾)的最大连续子序列和为dp[i]。连续的就得包括结尾元素,不连续就不需要了。