POJ 2192 Zipper

来源:互联网 发布:有趣的网站 知乎 网盘 编辑:程序博客网 时间:2024/06/07 05:18

一道简单DP【然而对于我来说还是难,看了很多题解才明白】

题目大意:输入字符串a,b,c 要求判断c是否有a,b中的个字符保持原有顺序组合而成。

算法思想:

DP

用dp[i][j]表示a的前0~i-1共i个字符和b的前0~j-1共j个字符是否构成c[i+j-1].

状态转换方程:

if(i>=1&&c[i+j-1]==a[i-1])

dp[i][j]=dp[i][j]||dp[i-1][j](如果dp[i-1][j]是真的话,通过c[i+j-1]==a[i-1]就知dp[i][j]也为真,否则为假)

if(j>=1&&c[i+j-1]==b[j-1])

dp[i][j]=dp[i][j]||dp[i][j-1]


注意:下标问题 dp[1][1]表示有a的前1个字符(即a[0])和b的前一个字符(即b[0]),能否组成c[1+1-1](即c[0]+c[1])

#include<iostream>#include<algorithm>#include<cstring>using namespace std;int main(){int t,m=0;cin >> t;while (t--){char s1[205];char s2[205];char s3[405];int dp[205][205];cin >> s1;cin >> s2;cin >> s3;memset(dp, 0, sizeof(dp));int len1 = strlen(s1);int len2 = strlen(s2);if (s1[0] == s3[0]){dp[1][0] = 1;}if (s2[0] == s3[0]){dp[0][1] = 1;}for (int i = 0; i <= len1; i++){for (int j = 0; j <= len2; j++){if (i >= 1 &&dp[i-1][j]&&(s3[i + j - 1] == s1[i - 1])){dp[i][j] = 1;}if (j >= 1 &&dp[i][j-1]&& (s3[i + j - 1] == s2[j - 1])){dp[i][j] = 1;}}}cout << "Data set "<<++m<<": ";if (dp[len1][len2]){cout << "yes" << endl;}else{cout << "no" << endl;}}return 0;}


0 0