暴力法
class Solution {
public:
int findLength(vector<int>& nums1, vector<int>& nums2) {
int res = 0;
for (int i = 0; i < nums1.size(); i++) {
for (int j = 0; j < nums2.size(); j++) {
int k = 0, len = 0;
while (nums1[i + k] == nums2[j + k]&&i+k<nums1.size()&&j+k<nums2.size()) {
k++;
len++;
}
res = max(res, len);
}
}
return res;
}
};
while中的条件一定要写完整,避免数组越界。每次都错
class Solution {
public:
int lengthOfLIS(vector<int>& nums) {
vector<int> dp(nums.size()+1,1);
int res=1;
for(int i=1;i<nums.size();i++){
for(int j=0;j<i;j++){
if(nums[j]<nums[i]){
dp[i]=max(dp[j]+1,dp[i]);
res=max(res,dp[i]);
}
}
}
return res;
}
};
二层循环条件是j<i,每次都错。
class Solution {
public:
int findLengthOfLCIS(vector<int>& nums) {
vector<int> dp(nums.size()+1,1);
int res=1;
for(int i=1;i<nums.size();i++){
if(nums[i]>nums[i-1]){
dp[i]=dp[i-1]+1;
res=max(res,dp[i]);
}
}
return res;
}
};
class Solution {
public:
int findLength(vector<int>& nums1, vector<int>& nums2) {
vector<vector<int>> dp(nums1.size()+1,vector<int>(nums2.size()+1,0));
int res=0;
for(int i=1;i<=nums1.size();i++){
for(int j=1;j<=nums2.size();j++){
if(nums1[i-1]==nums2[j-1]){
dp[i][j]=dp[i-1][j-1]+1;
res=max(res,dp[i][j]);
}
}
}
return res;
}
};
dp[i][j]表示的是以i-1,j-1结尾的最长重复子数组,所以if(nums1[i-1]==nums2[j-1]);
所以避免了初始化,因为dp[i][0]和dp[0][j]表示的就是-1和i-1,j-1的关系,没有意义,自动初始化为0.如果定义 dp[i][j]为 以下标i为结尾的A,和以下标j 为结尾的B,那么 第一行和第一列毕竟要进行初始化,如果nums1[i] 与 nums2[0] 相同的话,对应的 dp[i][0]就要初始为1, 因为此时最长重复子数组为1。 nums2[j] 与 nums1[0]相同的话,同理。
class Solution {
public:
int longestCommonSubsequence(string text1, string text2) {
vector<vector<int>> dp(text1.size()+1,vector<int>(text2.size()+1,0));
int res=0;
for(int i=1;i<=text1.size();i++){
for(int j=1;j<=text2.size();j++){
if(text1[i-1]==text2[j-1]){
dp[i][j]=dp[i-1][j-1]+1;
res=max(res,dp[i][j]);
}
else{
dp[i][j]=max(dp[i-1][j],dp[i][j-1]);
res=max(res,dp[i][j]);
}
}
}
return res;
}
};
class Solution {
public:
int maxUncrossedLines(vector<int>& nums1, vector<int>& nums2) {
vector<vector<int>> dp(nums1.size()+1,vector<int>(nums2.size()+1,0));
int res=0;
for(int i=1;i<=nums1.size();i++){
for(int j=1;j<=nums2.size();j++){
if(nums1[i-1]==nums2[j-1]){
dp[i][j]=dp[i-1][j-1]+1;
res=max(res,dp[i][j]);
}
else{
dp[i][j]=max(dp[i-1][j],dp[i][j-1]);
res=max(res,dp[i][j]);
}
}
}
return res;
}
};
和上题一样
class Solution {
public:
int maxSubArray(vector<int>& nums) {
vector<int> dp(nums.size()+1,0);
dp[0]=nums[0];
if(nums.size()==1) return nums[0];
int res=dp[0];
for(int i=1;i<nums.size();i++){
dp[i]=max(nums[i],dp[i-1]+nums[i]);
res=max(res,dp[i]);
}
return res;
}
};
class Solution {
public:
bool isSubsequence(string s, string t) {
vector<vector<int>> dp(s.size()+1,vector<int>(t.size()+1,0));
int res=0;
for(int i=1;i<=s.size();i++){
for(int j=1;j<=t.size();j++){
if(s[i-1]==t[j-1]){
dp[i][j]=dp[i-1][j-1]+1;
res=max(res,dp[i][j]);
}
else{
dp[i][j]=dp[i][j-1];
res=max(res,dp[i][j]);
}
}
}
if(res==s.size()) return 1;
return 0;
}
};
class Solution {
public:
int numDistinct(string s, string t) {
vector<vector<unsigned long long>> dp(s.size() + 1, vector<unsigned long long>(t.size() + 1));
for (int i = 0; i < s.size(); i++) dp[i][0] = 1;
for (int j = 1; j < t.size(); j++) dp[0][j] = 0;
for (int i = 1; i <= s.size(); i++) {
for (int j = 1; j <= t.size(); j++) {
if (s[i - 1] == t[j - 1]) {
dp[i][j] = dp[i - 1][j - 1] + dp[i - 1][j];
} else {
dp[i][j] = dp[i - 1][j];
}
}
}
return dp[s.size()][t.size()];
}
};
583. 两个字符串的删除操作 - 力扣(LeetCode)
class Solution {
public:
int minDistance(string word1, string word2) {
vector<vector<int>> dp(word1.size() + 1, vector<int>(word2.size() + 1));
for (int i = 0; i <= word1.size(); i++) dp[i][0] = i;
for (int j = 0; j <= word2.size(); j++) dp[0][j] = j;
for (int i = 1; i <= word1.size(); i++) {
for (int j = 1; j <= word2.size(); j++) {
if (word1[i - 1] == word2[j - 1]) {
dp[i][j] = dp[i - 1][j - 1];
} else {
dp[i][j] = min(dp[i - 1][j] + 1, dp[i][j - 1] + 1);
}
}
}
return dp[word1.size()][word2.size()];
}
};
class Solution {
public:
int minDistance(string word1, string word2) {
vector<vector<int>> dp(word1.size()+1,vector<int>(word2.size()+1,0));
for(int i=0;i<=word1.size();i++) dp[i][0]=i;
for(int i=0;i<=word2.size();i++) dp[0][i]=i;
for(int i=1;i<=word1.size();i++){
for(int j=1;j<=word2.size();j++){
if(word1[i-1]==word2[j-1]){
dp[i][j]=dp[i-1][j-1];
}
else{
dp[i][j]=min({dp[i-1][j]+1,dp[i][j-1]+1,dp[i-1][j-1]+1});
}
}
}
return dp[word1.size()][word2.size()];
}
};
蓝桥杯2023年第十四届省赛真题-更小的数(区间DP)-优快云博客
#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N=5e3+10;
int dp[N][N];
int n;
string s;
int ans=0;
signed main()
{
ios::sync_with_stdio(false);cin.tie(0);
cin>>s;
for(int len=2;len<=s.size();len++){
for(int i=0;i+len-1<s.size();i++){
int j=i+len-1;
if(s[i]>s[j]) dp[i][j]=1;
else if(s[i]<s[j]) dp[i][j]=0;
else dp[i][j]=dp[i+1][j-1];
ans+=dp[i][j];
}
}
cout<<ans;
return 0;
}
再做子序列问题时候,如果枚举字符串两个端点答案不对,试试先枚举字符串长度。