#include <iostream>
#include <vector>
#include <numeric>
#include <string>
#include <unordered_set>
using namespace std;
struct TreeNode{
int val = 0;
TreeNode* left = nullptr;
TreeNode* right = nullptr;
TreeNode(int val_):val(val_)
{}
};
int fib(int n)
{
if( n < 2)return n;
vector<int>dp(n + 1);
dp[0] = 0;
dp[1] = 1;
for(int i = 2; i <= n; ++i)
{
dp[i] = dp[i-1] + dp[i-2];
}
return dp[n];
}
int climbStairs(int n)
{
if(n <= 2)return n;
vector<int>dp(n+1);
dp[1] = 1;
dp[2] = 2;
for(int i = 3; i <= n; ++i)
{
dp[i] = dp[i-1] + dp[i-2];
}
return dp[n];
}
int climbStairs_m(int n,int m)
{
vector<int>dp(n+1,0);
dp[0] = 1;
for(int i = 1; i <= n; ++i)
{
for(int j = 1;j <= m; ++j)
{
if(i - j >= 0)dp[i]+=dp[i-j];
}
}
return dp[n];
}
int minCostClimbStairs(const vector<int>& cost)
{
vector<int>dp(cost.size());
dp[0] = cost[0];
dp[1] = cost[1];
for(int i = 2; i < cost.size(); ++i)
{
dp[i] = min(dp[i-1],dp[i-2]) + cost[i];
}
return min(dp[cost.size() - 1],dp[cost.size() - 2]);
}
int uniquePath(int m, int n)
{
vector<vector<int>>dp(m,vector<int>(n,0));
for(int i = 0; i < m; ++i)
{
dp[i][0] = 1;
}
for(int i = 0; i < n; ++i)
{
dp[0][i] = 1;
}
for(int i = 1;i < m; ++i)
{
for(int j = 1; j < n; ++j)
{
dp[i][j] = dp[i-1][j] + dp[i][j-1];
}
}
return dp[m-1][n-1];
}
int uniquePathWithObstackles(const vector<vector<int>>& obstackles)
{
int m = obstackles.size(), n = obstackles[0].size();
vector<vector<int>>dp(m,vector<int>(n,0));
for(int i = 0; i < m && obstackles[i][0] == 0 ; ++i)dp[i][0] = 1;
for(int i = 0; i < n && obstackles[0][i] == 0 ; ++i)dp[0][i] = 1;
for(int i = 1; i < m; ++i)
{
for(int j = 1; j < n; ++j)
{
if(obstackles[i][j] == 1) continue;
dp[i][j] = dp[i-1][j] + dp[i][j-1];
}
}
return dp[m-1][n-1];
}
int intergerBreak(int n)
{
vector<int>dp(n+1,0);
dp[2] = 1;
for(int i = 3; i <= n; ++i)
{
for(int j = 1; j < i-1; ++j)
{
dp[i] = max(dp[i],max(j * (i -j),j * dp[i-j]));
}
}
return dp[n];
}
int numTrees(int n)
{
vector<int>dp(n + 1);
dp[0] = 1;
for(int i = 0; i <= n; ++i)
{
for(int j = 1;j <= i; ++j)
{
dp[i] += dp[j - 1] * dp[i-j];
}
}
return dp[n];
}
bool canPartition(const vector<int>& nums)
{
int sum = accumulate(nums.begin(),nums.end(),0);
if(sum % 2 == 1)return false;
int target = sum / 2;
vector<int>dp(10001,0);
for(int i = 0; i < nums.size(); ++i)
{
for(int j = target; j >= nums[i]; --j)
{
dp[j] = max(dp[j],dp[j-nums[i]]+nums[i]);
}
}
return dp[target]==target;
}
int zeroOneBag(const vector<int>& weight, const vector<int>& value,int bagWeight)
{
vector<vector<int>>dp(weight.size() + 1, vector<int>(bagWeight+1,0));
// for(int i = 0; i < weight.size(); ++i)
// {
// dp[i][0] = 0;
// }
for(int j = bagWeight; j >= weight[0]; --j)
{
dp[0][j] = dp[0][j-weight[0]]+value[0];
}
for(int i = 1; i < weight.size(); ++i)
{
for(int j = 0; j <= bagWeight; ++j)
{
if(j < weight[i])dp[i][j] = dp[i-1][j];
else
{
dp[i][j] = max(dp[i-1][j],dp[i-1][j-weight[i]]+value[i]);
}
}
}
return dp[weight.size()-1][bagWeight];
}
int zeroOneBag_1D(const vector<int>& weight, const vector<int>& value,int bagWeight)
{
vector<int>dp(bagWeight + 1,0);
for(int i = 0; i < weight.size(); ++i)
{
for(int j = bagWeight; j >= weight[i];--j)
{
dp[j] = max(dp[j],dp[j-weight[i]]+value[i]);
}
}
return dp[bagWeight];
}
int lastStoneWeight(const vector<int>& stones)
{
int sum = accumulate(stones.begin(),stones.end(),0) / 2;
vector<int>dp(15001,0);
int target = sum / 2;
for(int i = 0; i < stones.size(); ++i)
{
for(int j = target; j >= stones[i];--j)
{
dp[j] = max(dp[j],dp[j-stones[i]]+stones[i]);
}
}
cout << dp[target] << endl;
return sum - dp[target] - dp[target];
}
int findTargetSumWays(const vector<int>nums,int s)
{
//left + right = sum , left - right = target ->left = (target + sum) / 2
int sum = accumulate(nums.begin(),nums.end(),0);
if(s > sum || (s + sum) / 2 == 1)return 0;
int bagSize = (s + sum) / 2;
vector<int>dp(bagSize + 1,0);
dp[0] = 1;
for(int i = 0; i < nums.size(); ++i)
{
for(int j = bagSize;j>=nums[i];--j)
{
dp[j]+=dp[j-nums[i]];
}
}
return dp[bagSize];
}
int findMaxForm(const vector<string>& strs, int m , int n)
{
vector<vector<int>>dp(m+1,vector<int>(n + 1,0));
for(string str:strs)
{
int oneNum = 0, zeroNum = 0;
for(char c:str)
{
if(c == '0')++zeroNum;
else ++oneNum;
}
for(int i = m; i >= zeroNum;--i)
{
for(int j = n; j >= oneNum; --j)
{
dp[i][j] = max(dp[i][j],1 + dp[i-zeroNum][j-oneNum]);
}
}
}
return dp[m][n];
}
int change(const vector<int>& coins,int amount)
{
vector<int>dp(amount+1,0);
dp[0] = 1;
for(int i = 0; i < coins.size(); ++i)
{
for(int j = coins[i]; j <= amount; ++j)
{
dp[j]+=dp[j-coins[i]];
}
}
return dp[amount];
}
int combinationSum4(const vector<int>& nums, int target)
{
vector<int>dp(target + 1, 0);
dp[0] = 1;
for(int i = 0; i <= target; ++i)
{
for(int j = 0; j < nums.size(); ++j)
{
if(i >= nums[j] && dp[i] + dp[i - nums[j]] <INT_MAX)
{
dp[i]+=dp[i-nums[j]];
}
}
}
return dp[target];
}
int coinChange(const vector<int>&nums,int amount)
{
vector<int>dp(amount + 1,INT_MAX);
dp[0] = 0;
for(int i = 0; i < nums.size(); ++i)
{
for(int j = nums[i];j <= amount; ++j)
{
if(dp[j - nums[i]]!= INT_MAX)
{
dp[j] = min(dp[j],dp[j-nums[i]] + 1);
}
}
}
if(dp[amount] == INT_MAX)return -1;
return dp[amount];
}
int numSquares(int n)
{
vector<int>dp(n+1,INT_MAX);
dp[0] = 0;
for(int i = 0; i <= n; ++i)
{
for(int j = 1; j * j <= i; ++j)
{
dp[i] = min(dp[i],dp[i - j * j]+1);
}
}
return dp[n];
}
bool wordBreak(string s, const vector<string>& wordDict)
{
vector<bool>dp(s.size() + 1, false);
unordered_set<string>set(wordDict.begin(),wordDict.end());
dp[0] = true;
for(int i = 1; i <= s.size(); ++i)
{
for(int j = 0; j < i; ++j)
{
string word = s.substr(j,i - j);
if(set.find(word)!= set.end()&&dp[j])
{
dp[i] = true;
}
}
}
return dp[s.size()];
}
int multiBag(vector<int>&weight,vector<int>&value,int bagWeight,vector<int>& nums)
{
for(int i = 0;i < nums.size(); ++i)
{
while(nums[i] > 1)
{
weight.push_back(weight[i]);
value.push_back(value[i]);
--nums[i];
}
}
vector<int>dp(bagWeight + 1, 0);
for(int i = 0; i < value.size(); ++i)
{
for(int j = bagWeight; j >= weight[i];--j)
{
dp[j] = max(dp[j],dp[j-weight[i]]+value[i]);
}
}
return dp[bagWeight];
}
int rob(const vector<int>& nums)
{
int n = nums.size();
if(n == 0)return 0;
if(n == 1) return nums[0];
vector<int>dp(n,INT_MIN);
dp[0] = nums[0];
dp[1] = max(nums[0],nums[1]);
for(int i = 2; i < nums.size(); ++i)
{
dp[i] = max(dp[i-1],dp[i-2]+nums[i]);
}
return dp[nums.size()-1];
}
int rob_h(const vector<int>& nums,int start,int end)
{
if(start == end)return nums[start];
vector<int>dp(nums.size());
dp[start]=nums[start];
dp[start+1]=max(nums[start],nums[start+1]);
for(int i = start + 2; i <= end; ++i)
{
dp[i] = max(dp[i-2]+nums[i],dp[i-1]);
}
return dp[end];
}
int robII(const vector<int>& nums)
{
int n = nums.size();
if(n == 0)return 0;
if(n == 1)return nums[0];
return max(rob_h(nums,0,nums.size() - 2),rob_h(nums,1,nums.size() - 1));
}
vector<int>robTree(TreeNode* root)
{
if(nullptr == root)return {0,0};
vector<int>left = robTree(root->left);
vector<int>right = robTree(root->right);
int Rob = root->val + left[0] + right[0];
int NoRob = max(left[0],right[1]) +max(left[1],right[0]);
return {NoRob,Rob};
}
int robIII(TreeNode* root)
{
auto res = robTree(root);
return *max_element(res.begin(),res.end());
}
int maxProfit(const vector<int>& prices)
{
int n = prices.size();
if(n == 0) return 0;
vector<vector<int>>dp(n,vector<int>(2,0));
dp[0][0] = 0;
dp[0][1] = -prices[0];
for(int i = 1; i < prices.size(); ++i)
{
dp[i][0] = max(dp[i-1][1]+prices[i],dp[i-1][0]);
dp[i][1] = max(dp[i-1][1],-prices[i]);//只能买卖一次,所以不能是dp[i-1][0]-prices[i]
}
return dp[prices.size() - 1][0] ;
}
int maxProfitII(const vector<int>& prices)
{
int n = prices.size();
if(n == 0) return 0;
vector<vector<int>>dp(n,vector<int>(2,0));
dp[0][0] = 0;
dp[0][1] = -prices[0];
for(int i = 1; i < prices.size(); ++i)
{
dp[i][0] = max(dp[i-1][1]+prices[i],dp[i-1][0]);
dp[i][1] = max(dp[i-1][1],dp[i-1][0]-prices[i]);//可以买卖多次,所以这里是dp[i-1][0]-prices[i]
}
return dp[prices.size() - 1][0] ;
}
int maxProfitIII(const vector<int>& prices)
{
//0:没有操作 1:第一次买入 2:第一次卖出 3:第二次买入 4:第二次卖出
int n = prices.size();
if(n == 0)return 0;
vector<vector<int>>dp(n,vector<int>(5,0));
dp[0][1] = -prices[0];
dp[0][3] = -prices[0];
for(int i = 1; i < n; ++i)
{
dp[i][0] = dp[i-1][0];
dp[i][1] = max(dp[i-1][1],dp[i-1][0]-prices[i]);
dp[i][2] = max(dp[i-1][2],dp[i-1][1]+prices[i]);
dp[i][3] = max(dp[i-1][3],dp[i-1][2]-prices[i]);
dp[i][4] = max(dp[i-1][4],dp[i-1][3]+prices[i]);
}
return dp[prices.size()-1][4];
}
int maxProfit(const vector<int>& nums, int k)
{
int n = nums.size();
if(0 == n)return 0;
vector<vector<int>>dp(n,vector<int>(2 * k + 1,0));
for(int j = 1; j < 2*k; j += 2)
{
dp[0][j] = -nums[0];
}
for(int i = 1; i < nums.size(); ++i)
{
for(int j = 0; j < 2 * k - 1; j += 2)
{
dp[i][j + 1] = max(dp[i-1][j + 1],dp[i-1][j] - nums[i]);
dp[i][j + 2] = max(dp[i-1][j + 2],dp[i-1][j+1]+nums[i]);
}
}
return dp[nums.size() - 1][2 * k];
}
int maxProfit_cold(const vector<int>& nums)
{
//状态一:买入股票状态(是今天买入,或者之前买入一直没卖)
//状态二: 保持卖出股票状态(两天前就卖出了,度过冷冻期,没操作)
//状态三:今天卖出股票
//状态四:今天为冷冻期
int n = nums.size();
if(0 == n)return 0;
vector<vector<int>>dp(n,vector<int>(4,0));
dp[0][0] = -nums[0];
for(int i = 1; i < n; ++i)
{
dp[i][0] = max(dp[i-1][0],max(dp[i-1][3],dp[i-1][1]) - nums[i]) ;
dp[i][1] = max(dp[i-1][1],dp[i-1][3]);
dp[i][2] = dp[i-1][0] + nums[i];
dp[i][3] = dp[i-1][2];
}
return max(dp[n-1][3],max(dp[n-1][1],dp[n-1][2]));
}
int maxProfit_fee(const vector<int>& prices, int fee)
{
int n = prices.size();
vector<vector<int>>dp(n,vector<int>(2,0));
dp[0][1] = -prices[0];
for(int i = 1; i < n; ++i)
{
dp[i][0] = max(dp[i-1][0],dp[i-1][1]+prices[i]-fee);
dp[i][1] = max(dp[i-1][1],dp[i-1][0]-prices[i]);
}
return dp[n-1][0];
}
int lengthOfList(const vector<int>& nums)
{
int n = nums.size();
if(n <= 1)return n;
vector<int>dp(n,1);
for(int i = 1; i < n; ++i)
{
for(int j = 0; j < i; ++j)
{
if(nums[i] > nums[j])dp[i] = max(dp[i], 1 + dp[j]);
}
}
return *max_element(dp.begin(),dp.end());
}
int lengthOfLCIS(const vector<int>& nums)
{
int n = nums.size();
if(0 == n)return 0;
vector<int>dp(n,1);
for(int i = 0; i < n - 1; ++i)
{
if(nums[i] < nums[i + 1])
{
dp[i + 1] = 1 + dp[i];
}
}
return *max_element(dp.begin(),dp.end());
}
int findLength(const vector<int>&A, const vector<int>&B)
{
int m = A.size(),n = B.size();
vector<vector<int>>dp(m + 1,vector<int>(n + 1,0));
int res = 0;
for(int i = 1; i <= m; ++i)
{
for(int j = 1; j <= n; ++j)
{
if(A[i-1] == B[j-1])
{
dp[i][j] = 1 + dp[i-1][j-1];
}
if(dp[i][j] > res)res = dp[i][j];
}
}
return res;
}
int lcs(string s1,string s2)
{
int m = s1.size(), n = s2.size();
vector<vector<int>>dp(m+1,vector<int>(n+1,0));
for(int i = 1; i <= m ; ++i)
{
for(int j = 1; j <= n; ++j)
{
if(s1[i-1] == s2[j-1])
{
dp[i][j] = 1 + dp[i-1][j-1];
}
else
{
dp[i][j] = max(dp[i-1][j],dp[i][j-1]);
}
}
}
return dp[m][n];
}
int maxUncrossLines(const vector<int>& nums1, const vector<int>& nums2)
{
int m = nums1.size(), n = nums2.size();
vector<vector<int>>dp(m+1,vector<int>(n+1,0));
for(int i = 1; i <= m; ++i)
{
for(int j = 1; j <= n; ++j)
{
if(nums1[i-1] == nums2[j-1])
{
dp[i][j] = 1 + dp[i-1][j-1];
}
else
{
dp[i][j] = max(dp[i-1][j],dp[i][j-1]);
}
}
}
return dp[m][n];
}
int maxSubArray(const vector<int>& nums)
{
int n = nums.size();
if(0 == n) return 0;
vector<int>dp(n,0);
dp[0] = nums[0];
for(int i = 1; i < n; ++i)
{
dp[i] = max(nums[i] + dp[i-1],nums[i]);
}
return *max_element(dp.begin(),dp.end());
}
bool isSubsequence(string s, string t)
{
int m = s.size(), n = t.size();
vector<vector<int>>dp(m + 1, vector<int>(n + 1,0));
for(int i = 1; i <= m; ++i)
{
for(int j = 1; j <= n; ++j)
{
if(s[i-1] == t[j-1])
{
dp[i][j] = 1 + dp[i-1][j-1];
}
else dp[i][j] = dp[i][j-1];
}
}
if(dp[m][n] == s.size())return true;
else return false;
}
int numsDistinct(string s, string t)
{
int m = s.size(), n = t.size();
vector<vector<int>>dp(m+1,vector<int>(n+1,0));
for(int i = 0; i < m; ++i)dp[i][0] = 1;
for(int j = 1; j < n; ++j)dp[0][j] = 0;
for(int i = 1; i <= m; ++i)
{
for(int j = 1; j <= n; ++j)
{
if(s[i]==t[j])
{
dp[i][j] = dp[i-1][j-1] + dp[i-1][j];
}
else
{
dp[i][j] = dp[i-1][j];
}
}
}
return dp[m][n];
}
int minDistance(string s, string t)
{
int m = s.size(), n = t.size();
vector<vector<int>>dp(m + 1, vector<int>(n + 1, 0));
for(int i = 0; i < m; ++i)dp[i][0] = i;
for(int j = 0; j < n; ++j)dp[0][j] = j;
for(int i = 1; i <= m; ++i)
{
for(int j = 1; j <= n; ++j)
{
if(s[i-1] == t[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] + 2});
}
}
}
return dp[m][n];
}
int minEditDistance(string s, string t)
{
int m = s.size(), n = t.size();
vector<vector<int>>dp(m+1,vector<int>(n+1,0));
for(int i = 0; i < m; ++i)dp[i][0] = i;
for(int j = 0; j < n; ++j)dp[0][j] = j;
for(int i = 1; i <= m; ++i)
{
for(int j = 1; j <= n; ++j)
{
if(s[i-1] == t[j-1])
{
dp[i][j] = dp[i-1][j-1];
}
else{
dp[i][j] = min({dp[i-1][j-1],dp[i][j-1],dp[i-1][j]}) + 1;
}
}
}
return dp[m][n];
}
int countSubStrings(string s)
{
int n = s.size(),res = 0;
vector<vector<bool>>dp(n,vector<bool>(n,false));
for(int i = n - 1; i >= 0; --i)
{
for(int j = i; j <= s.size(); ++j)
{
if(s[i] == s[j])
{
if(j - i <= 1)
{
++res;
dp[i][j] = true;
}
else if(dp[i+1][j-1])
{
++res;
dp[i][j] = true;
}
}
}
}
return res;
}
int longestHuiwenSubSqueence(string s)
{
int n = s.size();
vector<vector<int>>dp(n,vector<int>(n,0));
for(int i = 0; i < n; ++i)dp[i][i] = 1;
for(int i = s.size() - 1; i >= 0; --i)
{
for(int j = i + 1; j < n; ++j)
{
if(s[i] == s[j])
{
dp[i][j] = dp[i+1][j-1]+2;
}
else
{
dp[i][j] = max(dp[i+1][j],dp[i][j-1]);
}
}
}
return dp[0][n-1];
}
int main()
{
//LeetCode509 斐波那契序列
cout << fib(4) << endl;
//LeetCode70 爬楼梯
cout << climbStairs(3) << endl;
cout << climbStairs_m(3,2) << endl;//变体为完全背包问题
//LeetCode746 使用最小花费爬楼梯
vector<int>cost{1,100,1,1,1,100,1,1,100,1};
cout << minCostClimbStairs(cost) << endl;
//LeetCode62 不同路径
int m = 3, n = 7;
cout << uniquePath(m,n) << endl;
//LeetCode63 不同路径II
vector<vector<int>>path{{0,0,0},{0,1,0},{0,0,0}};
cout << uniquePathWithObstackles(path) << endl;
//LeetCode343 整数拆分
cout << intergerBreak(10) << endl;
//LeetCode96不同的二叉搜索树
cout << numTrees(3) << endl;
//背包问题
//0-1背包
vector<int>weight{1,3,4};
vector<int>value{15,20,30};
int bagweight = 4;
cout << zeroOneBag(weight,value,bagweight) << endl;
cout << zeroOneBag_1D(weight,value,bagweight) << endl;
//LeetCode416 分割等和子集
vector<int>nums{1,5,11,5};
cout << canPartition(nums) << endl;
//LeetCode1049 最后一块石头的重量II
vector<int>stones{2,7,4,1,8,1};
cout << lastStoneWeight(stones) << endl;
//LeetCode494 目标和
nums = {1,1,1,1,1};
int s = 3;
cout << findTargetSumWays(nums,s) << endl;
//LeetCode474 一和零
vector<string>strs{"10","0001","111001","1","0"};
m = 5, n = 3;
cout << findMaxForm(strs,m,n) << endl;
//LeetCode518 零钱兑换II
vector<int>coins{1,2,5};
int amount = 5;
cout << change(coins,amount) << endl;
//LeetCode377 组合总和IV
nums = {1,2,3};
int target = 4;
cout << combinationSum4(nums,target) << endl;
//LeetCode322 零钱兑换
coins = {1,2,5};
amount = 11;
cout << coinChange(coins,amount) << endl;
//LeetCode279 完全平方数
cout << numSquares(12) << endl;
//LeetCode139 单词拆分
string str = "leetcode";
vector<string>wordDict{"leet","code"};
cout << wordBreak(str,wordDict) << endl;
//多重背包
weight = {1,3,4};
value = {15,20,30};
nums = {2,3,2};
cout << multiBag(weight,value,10,nums) << endl;
//打家劫舍
//LeetCode198 打家劫舍
nums = {2,7,9,3,1};
cout << rob(nums) << endl;
//LeetCode213 打家劫舍II
nums = {2,3,2};
cout << robII(nums) << endl;
//LeetCode337 打家劫舍III
TreeNode t1(3);
TreeNode t2(2);
TreeNode t3(3);
TreeNode t4(3);
TreeNode t5(1);
t1.left = &t2;
t1.right = &t3;
t2.right = &t4;
t3.right = &t5;
cout << robIII(&t1) << endl;
//买卖股票的最佳时机
//LeetCode121
nums = {7,1,5,3,6,4};
cout << maxProfit(nums) << endl;
//LeetCode122
cout << maxProfitII(nums) << endl;
//LeetCode123
nums = {3,3,5,0,0,3,1,4};
cout << maxProfitIII(nums) << endl;
//LeetCode188
nums = {2,4,1};
int k = 2;
cout << maxProfit(nums,k) << endl;
//LeetCode309 冷冻期
nums = {1,2,3,0,2};
cout << maxProfit_cold(nums) << endl;
//LeetCode714 含手续费
vector<int>prices{1,3,2,8,4,9};
int fee = 2;
cout << maxProfit_fee(prices,fee) << endl;
//LeetCode300 递增最长子序列
nums = {0,1,0,3,2,3};
cout << lengthOfList(nums) << endl;
//LeetCode674 最长连续递增序列
nums = {1,3,5,4,7};
cout << lengthOfLCIS(nums) << endl;
//LeetCode718
vector<int>A{1,2,3,2,1};
vector<int>B{3,2,1,4,7};
cout << findLength(A,B) << endl;
//LeetCode1143最长公共子序列
string s1 = "abcde", s2 = "ace";
cout << lcs(s1,s2) << endl;
//LeetCode1035 不相交的线
vector<int>nums1{1,4,2};
vector<int>nums2{1,2,4};
cout << maxUncrossLines(nums1, nums2) << endl;
//LeetCode53 最大子序和
nums = {-2,1,-3,4,-1,2,1,-5,4};
cout << maxSubArray(nums) << endl;
//LeetCode392 判断子序列
string s0 = "abc";
string t0 = "ahbgdc";
cout << isSubsequence(s0,t0) << endl;
//LeetCode115 不同的子序例
s0 = "rabbbit";
s1 = "rabbit";
cout << numsDistinct(s0,s1) << endl;
//LeetCode583 两个字符串的删除操作
s0 = "sea";
s1= "eat";
cout << minDistance(s0,s1) << endl;
//LeetCode72 编辑距离
s0 = "intention";
s1 = "execution";
cout << minEditDistance(s0,s1) << endl;
//LeetCode647 回文子串个数
s0 = "abc";
cout << countSubStrings(s0) << endl;
//LeetCode516 最长回文子序列
s0 = "bbbab";
cout << longestHuiwenSubSqueence(s0) << endl;
return 0;
}