[bzoj3304]带限制的最长公共子序列
用f[i][j][k]表示s1前i个字符、s2前j个字符的LCS且包括s3前k个字符的最长前缀,然后对其某一维滚动,实现时细节比较多
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define N 505 4 int l1,l2,l3,f[2][N][N]; 5 char s1[N],s2[N],s3[N]; 6 int main(){ 7 scanf("%s%s%s",s1,s2,s3); 8 l1=strlen(s1); 9 l2=strlen(s2); 10 l3=strlen(s3); 11 for(int i=1,p=1;i<=l1;i++,p^=1){ 12 memset(f[p],0,sizeof(f[p])); 13 for(int j=1;j<=l2;j++) 14 for(int k=0;k<=l3;k++){ 15 f[p][j][k]=max(max(f[p^1][j][k],f[p][j-1][k]),f[p][j][k]); 16 if ((s1[i-1]==s2[j-1])&&((!k)||(f[p^1][j-1][k]))){ 17 int kk=k+(s1[i-1]==s3[k]); 18 f[p][j][kk]=max(f[p][j][kk],f[p^1][j-1][k]+1); 19 } 20 } 21 } 22 if (!f[l1&1][l2][l3])printf("NO SOLUTION"); 23 else printf("%d",f[l1&1][l2][l3]); 24 }