PKU演習問メモ(8/9)
全く練習の成果が出ない。DP解けるようにならねえ。。。
No. | 問題名 | 問題の種類および解法 | 難易度 |
---|---|---|---|
2192 | Zipper | 動的計画法 | ★★☆☆☆ |
2192 Zipper
問題概要
文字列A,B,Cが与えられる。
A,Bの文字列をそれぞれの順番は変えず、任意に組み合わせてCの文字列を作れるかを判定せよ。
(例えば、catとtrerからtcraeteなどが作れる)
Cの文字数はAとBの文字数の和であり、A,Bの文字数は200以下である。
解法
動的計画法による。
dp[i][j]を、「Cのi文字までを、Aの先頭からj文字までと、Bの先頭からi-j文字までを使って作れるか」とすると、
dp[i+1][j+1]=dp[i][j] (A[j]==C[i]のとき)
dp[i+1][j]=dp[i][j] (B[i-j]==C[i]のとき)の漸化式が成り立つので解ける。
ソースコード
char A[201],B[201],C[401]; bool dp[2][201]; int main() { int cs; scanf("%d",&cs); rep(CS,cs) { scanf("%s %s %s",A,B,C); int l=strlen(A),m=strlen(B),n=strlen(C); rep(i,l+1)dp[0][i]=0; dp[0][0]=1; int cur=0,next=1; rep(i,n) { fill_n(dp[next],l+1,0); rep(j,i+1)if(dp[cur][j]) { if(j<l&&A[j]==C[i])dp[next][j+1]=1; if(i>=j&&B[i-j]==C[i])dp[next][j]=1; } swap(cur,next); } printf("Data set %d: %s\n",CS+1,dp[cur][l]?"yes":"no"); } return 0; }