题目大意:给出三个字符串,从分别从第一个字符串和第二个字符串中挑选子串a,b,用a和b组成第三个字符串,问可组成的子串有多少种。
解题思路:dp[i][j][k]表是用s1中的前i个字符和s2中的前j个字符的子串组成s3前k个字符的情况。
仿照http://www.cnblogs.com/yuzhaoxin/archive/2012/05/04/2483259.html
#include <cstdio> #include <cstring> #include <algorithm> using namespace std; int DP[45][45][45][45], A[4][45], top[4], vis[180], n; int DPS(int cur) { int &ans = DP[top[0]][top[1]][top[2]][top[3]]; if (ans != -1) return ans; if (cur == 5) return 0; int maxa = 0; for (int i = 0; i < 4; i++) { if (top[i] == n) continue; int color = A[i][top[i]]; top[i]++; if (vis[color]) { vis[color] = 0; maxa = max(maxa, DPS(cur-1) + 1); vis[color] = 1; } else { vis[color] = 1; maxa = max(maxa, DPS(cur+1)); vis[color] = 0; } top[i]--; } return ans = maxa; } int main() { while (scanf("%d", &n), n) { for (int i = 0; i < n; i++) for (int j = 0; j < 4; j++) scanf("%d", &A[j][i]); memset(DP, -1, sizeof(DP)); memset(top, 0, sizeof(top)); memset(vis, 0, sizeof(vis)); printf("%d\n", DPS(0)); } return 0; }