1. 程式人生 > >bzoj1566 [NOI2009]管道取珠

bzoj1566 [NOI2009]管道取珠

continue spl alt con class ret zoj str opened

傳送門:http://www.lydsy.com/JudgeOnline/problem.php?id=1566

【題解】

考慮表示的實際意義,相當於我取兩次球,得到方案完全相同的個數。

設$f_{i,j,k}$表示取了$i$個,第一種上面取$j$個,第二種上面取$k$個,隨便轉移。

復雜度$O(n^3)$。

技術分享
# include <stdio.h>
# include <string.h>
# include <iostream>
# include <algorithm>
// # include <bits/stdc++.h>

using
namespace std; typedef long long ll; typedef long double ld; typedef unsigned long long ull; const int M = 5e2 + 10; const int mod = 1024523; int f[2][M][M]; int nA, nB; char a[M], b[M]; inline void cadd(int &a, int b) { a += b; if(a >= mod) a -= mod; } int main() { cin >> nA >> nB; scanf(
"%s%s", a+1, b+1); reverse(a+1, a+nA+1); reverse(b+1, b+nB+1); int cur = 0, nxt = 1; f[cur][0][0] = 1; for (int i=0; i<nA+nB; ++i) { int end_num = min(nA, i); memset(f[nxt], 0, sizeof f[nxt]); for (int j=0, jj; j<=end_num; ++j) for (int k=0, kk; k<=end_num; ++k)
if(f[cur][j][k]) { jj = i - j, kk = i - k; if(jj > nB || kk > nB) continue; if(a[j+1] == a[k+1]) cadd(f[nxt][j+1][k+1], f[cur][j][k]); if(b[jj+1] == a[k+1]) cadd(f[nxt][j][k+1], f[cur][j][k]); if(a[j+1] == b[kk+1]) cadd(f[nxt][j+1][k], f[cur][j][k]); if(b[jj+1] == b[kk+1]) cadd(f[nxt][j][k], f[cur][j][k]); } swap(cur, nxt); } cout << f[cur][nA][nA]; return 0; }
View Code

bzoj1566 [NOI2009]管道取珠