现在做dp题有点感觉了,以前估计会觉得这题很难,现在觉得这是道不是很水的水题
dp[i][j]代表A里前i个加上B里前j个能不能组成C的前i+j个。
至于怎么想到的呢,n是200,有1000组数据,所以猜测要dp二维,然后很容易就想到了。
这里再考虑到C[i+j]的这个元素肯定是由A[i]或B[j]组成(即A的最末尾或B的最末尾,因为要保证原来的order)
所以这就变成了dp[i][j] = dp[i-1][j] | dp[i][j-1] (当然这是A[i]=B[j]=C[i+j])的情况。
接着想递归怎么写,每次要看正上方和左边的数值,所以从上到下从左到右就可以。边界条件是i=0或j=0的时候
===2018.9.7===
字符串dp的技巧性就是看最后一位,枚举这个字符是怎么得来的
1 #include<iostream> 2 #include<cstring> 3 using namespace std; 4 5 int dp[205][205];//dp[i][j] 6 char a[205],b[205],c[410]; 7 int cnt; 8 //string a1,b1,c1; 9 10 int main(){ 11 int t; cin>>t; 12 while(t--){ 13 memset(dp,0,sizeof(dp)); 14 cin>>a+1>>b+1>>c+1;//范围从1到strlen(a+1> 15 16 for(int i=0;i<=strlen(b+1);i++){ 17 bool same=true; 18 for(int j=0;j<=i;j++){ 19 if(b[j]!=c[j]) { same=false; break; } 20 } 21 if(same) dp[0][i]=1; 22 else dp[0][i]=0; 23 } 24 25 for(int i=0;i<=strlen(a+1);i++){ 26 bool same=true; 27 for(int j=0;j<=i;j++){ 28 if(a[j]!=c[j]) { same=false; break; } 29 } 30 if(same) dp[i][0]=1; 31 else dp[i][0]=0; 32 } 33 34 35 for(int i=1;i<=strlen(a+1);i++){ 36 for(int j=1;j<=strlen(b+1);j++){ 37 if( a[i]==c[i+j] ) dp[i][j]|=dp[i-1][j]; 38 if( b[j]==c[i+j] ) dp[i][j]|=dp[i][j-1]; 39 } 40 } 41 string ans; 42 if(dp[strlen(a+1)][strlen(b+1)]) ans="yes"; 43 else ans="no"; 44 45 cout<<"Data set "<<(++cnt)<<": "<<ans<<endl; 46 47 } 48 49 return 0; 50 }