转换一下题意,就相当于问t能不能和s中2个不相同的子串相同,我们可以将t串拆成2个子串t1,t2,得到状态dp[i][j][k]=0/1,表示s判断到i位,t1判断到j位,t2判断到k位,0/1表示是否满足
两个状态,s[i]与t1[j]相匹配,s[i]与t2[k]相匹配
dp[i+1][j+1][k] = dp[i][j][k]
dp[i+1][j][k+1] = dp[i][j][k]
因为dp的值只取0和1,我们可以优化dp函数,dp[i][j][k]可以变成dp[i][j] = k,这样可以消除一维,最后判断dp[s.size()][t1.size()]是否>=t2.size(),也就是匹配成功即可,复杂度为O(n^3)
#include<bits/stdc++.h> using namespace std; #define lowbit(x) ((x)&(-x)) typedef long long LL; int dp[405][405]; bool check(string s, string t) { int idx = 0; if(!t.size()) return true; for(int i = 0; i < s.size(); ++i) { if(s[i] == t[idx]) idx++; if(idx == t.size()) return true; } return false; } bool check(string s, string t1, string t2) { memset(dp, -1, sizeof(dp)); dp[0][0] = 0; for(int i = 0; i < s.size(); ++i) for(int j = 0; j <= t1.size(); ++j) if(dp[i][j] >= 0) { if(j<t1.size()&&s[i] == t1[j]) dp[i+1][j+1] = max(dp[i+1][j+1], dp[i][j]); if(dp[i][j]<t2.size()&&s[i] == t2[dp[i][j]]) dp[i+1][j] = max(dp[i+1][j], dp[i][j]+1); dp[i+1][j] = max(dp[i][j], dp[i+1][j]); } int s1 = dp[s.size()][t1.size()], s2 = t2.size(); if(s1 >= s2) return true; return false; } void run_case() { string s, t; cin >> s >> t; /* if(check(s, t)) { cout << "YES "; return; } */ for(int i = 0; i < t.size(); ++i) { string t1 = "", t2 = ""; for(int j = 0; j <= i; ++j) { t1 += t[j]; } for(int j = i+1; j < t.size(); ++j) t2 += t[j]; if(check(s, t1, t2)) { cout << "YES "; return; } } cout << "NO "; } int main() { ios::sync_with_stdio(false), cin.tie(0); //cout.setf(ios_base::showpoint);cout.precision(10); int t; cin >> t; while(t--) run_case(); cout.flush(); return 0; }