强化训练:day10(最长回文子串、买卖股票的最好时机(一)、过河卒)

前言

  做题链接:
  1. 最长回文子串
  2. 买卖股票的最好时机(一)
  3. 过河卒

1. 最长回文子串

1.1 题目描述

在这里插入图片描述

1.2 解题思路

  本题有好几种解决方法,中心扩展,马拉车,dp等,这里我采用了中心扩展,因为比较简单。
  中心扩展就是一次枚举每一个字符,然后充该字符位置向左右两边扩展,来进行搜索回文串。不过需要注意的是,回文串有奇数偶数的问题,所以每一个位置要扩展两次。
在这里插入图片描述

1.3 代码实现

class Solution {
public:

    int getLongestPalindrome(string str) 
    {
        int n = str.size();
        int ret = 0;
        for(int i = 0; i < n; i++)
        {
            // 奇数
            int left = i - 1, right = i + 1;
            while(left >= 0 && right < n && str[left] == str[right])
            {
                left--;
                right++;
            }
            ret = max(ret, right - left - 1);
            // 偶数
            left = i, right = i + 1;
            while(left >= 0 && right < n && str[left] == str[right])
            {
                left--;
                right++;
            }
            ret = max(ret, right - left - 1);
        }
        return ret;
    }
};

2. 买卖股票的最好时机(一)

2.1 题目描述

在这里插入图片描述

2.2 解题思路

  典型的dp问题,但是本题还有更简单的解决方式,因为只买卖一次,因此可以用贪心。
  也就是可以暴力枚举全部的买入卖出的所得利润,取最大值。

2.3 代码实现

#include <iostream>
using namespace std;
#include <vector>
int main()
{
    int n = 0; cin >> n;
    vector<int> nums(n);
    for(int i = 0; i < n; i++)
        cin >> nums[i];

    int prev = nums[0]; // 记录当前元素前面的最小值
    int ret = 0;
    // 枚举第i天卖出的利润
    for(int i = 0; i < n; i++)
    {
        ret = max(ret, nums[i] - prev);
        prev = min(prev, nums[i]);
    }
    cout << ret;
    return 0;
}

3. 过河卒

3.1 题目描述

在这里插入图片描述

3.2 解题思路

  路径dp问题,不过这个题需要注意的是卒开始出发的位置是[1,1],到达的地方是[n+1,m+1],所以在填dp表的时候需要注意。

3.3 代码实现

#include <iostream>
using namespace std;
int x,y,n,m;
long long dp[25][25];
int main()
{
    cin >> n >> m >> x >> y;
    dp[0][1] = 1; // 初始化

    x += 1; y += 1;  // 卒是从[1,1]开始的,所以提前给x,y加上1
    for(int i = 1; i <= n + 1; i++) // 到达n m实际是到达[n+1,m+1]
        for(int j = 1; j <= m + 1; j++)
        {
            if(i != x && j != y && abs(i -x) + abs(j - y) == 3 || (i == x && y == j))
            {
                dp[i][j] = 0;
            }
            else
            {
                dp[i][j] = dp[i-1][j] + dp[i][j-1];
            }
        }

    cout << dp[n+1][m+1];
    return 0;
}

总结

  dp问题简单的很简单,难的就很难的,需要大家多加练习。
  那么第十天的内容就到此结束了,如果大家发现有什么错误的地方,可以私信或者评论区指出喔。我会继续坚持训练的,希望能与大家共同进步!!!那么本期就到此结束,让我们下期再见!!觉得不错可以点个赞以示鼓励!

  • 5
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

不如小布.

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值