涉及算法:动态规划(dp)
这是一个多状态的线性dp问题。
解题分析:
字符串的长度是n,找到我们最后一个字符‘y’,假设它的下标是 i ,那么我们最终等结果就是 [0,i] 区间中的 "shy" 字符串的个数。
而我们要求 [0,i] 区间中的 "shy" 字符串的个数,也就就是要求 [0, i - 1] 区间中字符串 "sh" 的个数。
要求 [0, i - 1] 区间中字符串 "sh" 的个数,也就是要求 [0, i - 2] 区间中字符 's' 的个数
所以我们只需要知道 i 位置的 's' 的个数,然后去求出"sh"的个数,从而得到"shy" 的个数即可。
解题思路:
1. 状态表示:
三个数组:s[ i ] , h[ i ] , y[ i ]
s[ i ] :表示[0, i] 区间中字符 's' 的数量
h[ i ] :表示[0, i] 区间中字符 'sh' 的数量
y[ i ] :表示[0, i] 区间中字符 'shy' 的数量
那么最终结果就是 y[n - 1] 。
2. 状态转移方程
3. 初始化
由于上面都是由 i -1 位置退出来的,所以我们只需要初始化第一个位置即可:
对于s[0],需要判断是否为 's' ,如是,则为1,如不是则为0.
对于h[0],和y[0]都初始为 0 ,因为第一个位置不可能是 "sh"或"shy"。
4. 返回值
y[n-1]即为最终结果。
空间优化
我们其实不需要真的创建数组,直接通过三个整型类型的变量就可以来表示对应位置的数目了。
- s 表示遍历到当前位置 's' 的数量
- h 表示遍历到当前位置 "sh" 的数量
- y 表示遍历到当前位置 '"shy" 的数量
思路:
- 如果 str[i] 等于 's' ,则s++;
- 如果str[i] 等于 'h' ,则 h += s;
- 如果str[i] 等于 'y' ,则 y += h;
- 遍历结束,y 中存的就是这个字符串中"shy"的个数,所以最后返回 y 即可。
下面我们就是以空间优化的思路来写的代码:
#include <iostream>
#include <string>
using namespace std;
int n;
string str;
int main()
{
cin >> n >> str;
long long s = 0, h = 0, y = 0;
for(int i = 0; i < n; i++)
{
char ch = str[i];
if(ch == 's') s++;
else if(ch == 'h') h += s;
else if(ch == 'y') y += h;
}
cout << y << endl;
return 0;
}

京公网安备 11010502036488号