@ 代碼隨想錄算法訓練營第8周(C語言)|Day57(動態規劃)
Day53、動態規劃(● 1143.最長公共子序列 ● 1035.不相交的線 ● 53. 最大子序和 動態規劃 )
1143.最長公共子序列
題目描述
給定兩個字符串 text1 和 text2,返回這兩個字符串的最長公共子序列的長度。
一個字符串的 子序列 是指這樣一個新的字符串:它是由原字符串在不改變字符的相對順序的情況下刪除某些字符(也可以不刪除任何字符)后組成的新字符串。
例如,“ace” 是 “abcde” 的子序列,但 “aec” 不是 “abcde” 的子序列。兩個字符串的「公共子序列」是這兩個字符串所共同擁有的子序列。
題目解答
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],且我們繪制的直線不與任何其他連線(非水平線)相交。
以這種方法繪制線條,并返回我們可以繪制的最大連線數。
題目解答
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 ,找到一個具有最大和的連續子數組(子數組最少包含一個元素),返回其最大和。
題目解答
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]。連續的就得包括結尾元素,不連續就不需要了。