POJ 1692 Crossed Matchings(DP)

来源:互联网 发布:新浪2017中超球员数据 编辑:程序博客网 时间:2024/04/20 22:04

题意:两个序列,要选出交叉线,使得线的两点数字要相同,并且两条线两边的数字不能相同,问最多能弄出几组

思路:类似LCM,dp[i][j]表示两个i, j的方案,然后如果a[i] != b[j], 那么从i和j分别往前找到一个相同dp[i][j] = dp[k1][k2] + 2,剩下的转移就是dp[i][j] = max(dp[i - 1][j], dp[i][j - 1])

代码:

#include <cstdio>#include <cstring>#include <algorithm>using namespace std;const int N = 105;int t, n, m, a[N], b[N], dp[N][N];int main() {    scanf("%d", &t);    while (t--) {scanf("%d%d", &n, &m);for (int i = 1; i <= n; i++)    scanf("%d", &a[i]);for (int i = 1; i <= m; i++)    scanf("%d", &b[i]);memset(dp, 0, sizeof(dp));for (int i = 1; i <= n; i++) {    for (int j = 1; j <= m; j++) {dp[i][j] = max(dp[i - 1][j], dp[i][j - 1]);if (a[i] == b[j]) continue;int k1, k2;for (k1 = i - 1; k1; k1--)    if (a[k1] == b[j]) break;for (k2 = j - 1; k2; k2--)    if (b[k2] == a[i]) break;if (k1 && k2)    dp[i][j] = max(dp[i][j], dp[k1 - 1][k2 - 1] + 2);    }}printf("%d\n", dp[n][m]);    }    return 0;}


0 0
原创粉丝点击