http://poj.org/problem?id=2192
两种 深搜剪枝or动规
以下代码使用动规方法。
做了两题动规(poj 2192 & poj 1080),觉得关键在找到状态转移的方法和边界的处理上。
//
// main.cpp
// proj
//
// Created by yi chen on 13-10-10.
// Copyright (c) 2013年 yi chen. All rights reserved.
//POJ 2192 Zipper
#include <iostream>
#include <string>
using namespace std;
bool isZipper(string & s1, string & s2, string & s3){
int mapRows=(int)s1.length()+1, mapCols=(int)s2.length()+1;
bool **map=new bool* [mapRows];
for (int i=0; i<mapRows; i++) {
map[i]=new bool[mapCols];
memset(map[i], 0, sizeof(bool)*mapCols);
}
map[0][0]=true;
//边界处理
for (int i=1; i<mapRows; i++) {
if (map[i-1][0] && s1[i-1]==s3[i-1]) {
map[i][0]=true;
}else{
map[i][0]=false;
}
}
for (int j=1; j<mapCols; j++) {
if (map[0][j-1] && s2[j-1]==s3[j-1]) {
map[0][j]=true;
}else{
map[0][j]=false;
}
}
//状态转移
for (int i=1; i<mapRows; i++) {
for (int j=1; j<mapCols; j++) {
if (map[i][j-1] && s2[j-1]==s3[i+j-1]) { //左边的状态
map[i][j]=true;
}else if (map[i-1][j] && s1[i-1]==s3[i+j-1]) {// 上面的状态
map[i][j]=true;
}else{
map[i][j]=false;
}
}
}
bool res=map[s1.length()][s2.length()];
for (int i=0; i<mapRows; i++) {
delete [] map[i];
}
delete [] map;
return res;
}
int main()
{
int numOfCases = 0;
string s1,s2,s3;
cin>>numOfCases;
for (int i=1; i<=numOfCases; i++) {
cin>>s1;
cin>>s2;
cin>>s3;
bool res=isZipper(s1,s2,s3);
cout<<"Data set "<<i<<": ";
if(res){
cout<<"yes"<<endl;
}else{
cout<<"no"<<endl;
}
}
return 0;
}