您的位置:首页 > 其它

hdu 4545 魔法串 dp

2016-04-21 09:48 260 查看
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=4545

思路:设dp[i][j]为s1长度为i,s2长度为j能否成功匹配,状态出来后,详细的转移方程看代码

#include <cstdio>
#include <cstring>
#include <algorithm>

using namespace std;

char s1[1005], s2[1005];
int m;
bool g[30][30], dp[1005][1005];

void solve()
{
int len1 = strlen(s1);
int len2 = strlen(s2);
memset(dp, 0, sizeof(dp));
for (int i = 0; i <= len2; i++)
dp[0][i] = true; //s1长度为0时肯定和s2任意长度匹配,因为只要把s2全删掉就行了
for (int i = 1; i <= len1; i++)
{
for (int j = 1; j <= len2; j++)
{
if (dp[i][j - 1])
dp[i][j] = true; //第i个字符与第j-1个可以构成,那么删除第j个即可

else if (s1[i - 1] == s2[j - 1] && dp[i - 1][j - 1]) //前后两个i-1和j-1意义是不一样的,
dp[i][j] = true; //当前字符相等,并且s1长度为i-1和s2长度为j-1时匹配成功,那么当前肯定匹配成功

else if (g[s2[j - 1] - 'a'][s1[i - 1] - 'a'] && dp[i-1][j-1])
dp[i][j] = true;//和第二种情况一样,通过给定的转换
}
}
if (dp[len1][len2]) puts("happy");
else puts("unhappy");
}

int main()
{
int t, cas = 1;
scanf("%d", &t);
while (t--)
{
scanf("%s%s", s1, s2);
memset(g, false, sizeof(g));
scanf("%d", &m);
char u[5], v[5];
for (int i = 0; i < m; i++)
{
scanf("%s%s", u, v);
g[u[0] - 'a'][v[0] - 'a'] = true;
}
printf("Case #%d: ", cas++);
solve();
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  hdu 4545 dp