月月查华华的手机(贪心,dp)
月月查华华的手机
https://ac.nowcoder.com/acm/problem/23053
题解
类似于单调栈的思想(找右边满足某些性质的位置)
所以这道题可以预处理出每个位置的字符的右边离他最近的26个字母的位置。(如果不存在则是-1) 但是要注意的是,要在原数组之前添加一个额外的位置用来找到目标数组的第一个位置。
nxt[i][j] = nxt[i + 1][j]
动态规划从后往前遍历即可。
代码
#include<iostream> #include<algorithm> #include<cstdio> #include<climits> #include<cstring> #include<cstdlib> #include<cmath> #include<map> #include<set> #include<queue> #include<vector> #pragma GCC optimize(2) #pragma GCC optimize(3) #define ll long long #define LLMax LLONG_MAX #define LLMin LLONG_MIN #define Max INT_MAX #define Min INT_MIN #define FOR1(i,a,b) for(int i=(a);i<(b);i++) #define FOR2(i,a,b) for(int i=(a);i<=(b);i++) #define DWN(j,b,a) for(int j=(b);j>=(a);j--) #define SET0(a) memset(a,0,sizeof(a)) #define SET1(a) memset(a,-1,sizeof(a)) #define IOS ios_base::sync_with_stdio(0),cin.tie(0),cout.tie(0) const int INF=0x3f3f3f3f; const int NINF=-INF-1; const double PI=acos(-1); const int mod=1e9+7; const int maxn=3e6+5; using namespace std; char str[maxn]; int n; int nxt[maxn][30]; int main() { cin >> (str + 1); int o = strlen(str + 1); FOR1(i, 0, o) nxt[i][str[i + 1] - 'a'] = i + 1; for (int i = o - 1; i >= 0; i --) for (int j = 0; j < 26; j ++) if(!nxt[i][j]) nxt[i][j] = nxt[i + 1][j]; cin >> n; while (n --) { string s; cin >> s; int x = 0; bool flag = true; int m = s.length(); for (int i = 0; i < m; i ++) { x = nxt[x][s[i] - 'a']; if(!x) { flag = false; break; } } if(flag) puts("Yes"); else puts("No"); } }