Erase Subsequences - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
我们首先可以把 T 拆成两部分 L和R,再考虑L和R是否能从S中获取
那么我们可以设置出一个比较套路的dp状态:dp[i][j][k] 表示 S 前i位,成功匹配了L的前 j 位,R的前 k 位的状态是否成立
这个dp状态还是很好转移的:
for(int mid=1;mid<=n;mid++) // 把 T 分成 1~mid,mid+1~m { int L=mid,R=m-mid; for(int i=0;i<=n;i++) for(int j=0;j<=L;j++) for(int k=0;k<=R;k++) dp[i][j][k]=0; dp[0][0][0]=1; for(int i=1;i<=n;i++) for(int j=0;j<=L;j++) for(int k=0;k<=R;k++) { if(dp[i-1][j][k]==0) continue; dp[i][j][k]=1; if(a[i]==b[j+1]&&j<L) dp[i][j+1][k]=1; if(a[i]==b[mid+k+1]&&k<R) dp[i][j][k+1]=1; } if(dp[n][L][R]) { puts("YES"); return; } } puts("NO");
但是这个是 O(n^4)的复杂度,会TLE。
考虑优化dp状态。
显然 S 前i位,成功匹配了L的前 j 位的时候,此时一定是R的匹配位数越多越好。
所以我们再设置一个dp状态:dp[i][j]表示 S 前i位,成功匹配了L的前 j 位的时候,R最多能匹配几位。(这个dp状态跟 CF837D 凑10的状态十分相似)
(本题的难点还是在于dp状态的设置)
此时我们便可以优化 k 循环,以此优化时间复杂度变成 O(n^3)
Code:
// LUOGU_RID: 110736592 #include<bits/stdc++.h> using namespace std; #define ll long long #define mp make_pair #define pb push_back #define popb pop_back #define fi first #define se second #define popcount __builtin_popcount #define popcountll __builtin_popcountll const int N=410; //const int M=; //const int inf=(int)1e9; //const ll INF=(ll)1e18; int T,n,m; int dp[N][N]; char a[N],b[N]; inline int read() { int x=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();} return x*f; } void solve() { scanf("%s%s",a+1,b+1); n=strlen(a+1); m=strlen(b+1); for(int mid=1;mid<=m;mid++) { int L=mid,R=m-mid; for(int i=0;i<=n;i++) for(int j=0;j<=L;j++) dp[i][j]=-1; dp[0][0]=0; for(int i=1;i<=n;i++) for(int j=0;j<=L;j++) //dp[i-1][j]的值已知 { if(dp[i-1][j]==-1) continue; dp[i][j]=max(dp[i][j],dp[i-1][j]); if(a[i]==b[j+1]&&j<L) dp[i][j+1]=max(dp[i][j+1],dp[i-1][j]); int Rpos=dp[i-1][j]+mid+1; if(a[i]==b[Rpos]&&Rpos<=m) dp[i][j]=max(dp[i][j],dp[i-1][j]+1); } // printf("%d\n",mid); // for(int i=1;i<=n;i++) // for(int j=0;j<=L;j++) // printf("%d %d %d\n",i,j,dp[i][j]); if(dp[n][L]==R) { puts("YES"); return; } } puts("NO"); } int main() { // freopen("","r",stdin); // freopen("","w",stdout); // ios::sync_with_stdio(0); // cin.tie(0); T=read(); while(T--) solve(); return 0; }
标签:状态,ch,const,int,CF1303E,dp,define From: https://www.cnblogs.com/Willette/p/17426424.html