# Solution

per(i, l, 2)
rep(j, 1, l) {
if (dp[i][j] != 0x3f3f3f3f) {
if (tax2[j][st1[i - 1] - 'a'] > tax1[i][st1[i - 1] - 'a'])
dp[i - 1][j] = std::min(dp[i - 1][j], dp[i][j] + 1);
for (int k = 1; k <= j - 1; k++)
if (st2[k] == st1[i - 1])
dp[i - 1][k] = std::min(dp[i - 1][k], dp[i][j]);
}


# Code

#include <bits/stdc++.h>

#define fi first
#define se second
#define pb push_back
#define MP std::make_pair
#define PII std::pair<int, int>
#define all(x) (x).begin(), (x).end()
#define CL(a, b) memset(a, b, sizeof a)
#define rep(i, l, r) for (int i = (l); i <= (r); ++ i)
#define per(i, r, l) for (int i = (r); i >= (l); -- i)
#define PE(x, a) for (int x = head[a]; x;x = edge[x].next)

typedef long long ll;

template <class T>
inline void rd(T &x) {
char c = getchar(), f = 0; x = 0;
while (!isdigit(c)) f = (c == '-'), c = getchar();
while (isdigit(c)) x = x * 10 + c - '0', c = getchar();
x = f ? -x : x;
}

const int MAXN = 2000;

int l, dp[MAXN + 50][MAXN + 50], tax1[MAXN + 50][50], tax2[MAXN + 50][50], pp[MAXN + 50], vis[MAXN + 50], p[MAXN + 50], ans[MAXN + 50];

char st1[MAXN + 50], st2[MAXN + 50];

PII from[MAXN + 50][MAXN + 50];

void chkmin(int x, int y, int i, int j, int val) {
if (dp[x][y] > dp[i][j] + val)
dp[x][y] = dp[i][j] + val, from[x][y] = MP(i, j);
return;
}

void work(int x, int y) {
pp[x] = y;
int i = from[x][y].fi, j = from[x][y].se;
if (!i && !j) return;
work(i, j);
return;
}

void file() {
freopen("chinese.in", "r", stdin);
freopen("chinese.out", "w", stdout);
return;
}

int main() {
file();
int t;
rd(t);
while (t--) {
memset(vis, 0, sizeof(vis));
memset(p, 0, sizeof(p));
memset(ans, 0, sizeof(ans));
memset(dp, 0x3f, sizeof(dp));
for (int i = 1; i <= MAXN; i++)
for (int j = 1; j <= MAXN; j++)
from[i][j] = MP(0, 0);
memset(tax1, 0, sizeof(tax1));
memset(tax2, 0, sizeof(tax2));
scanf("%s", st1 + 1);
scanf("%s", st2 + 1);
l = strlen(st1 + 1);
per(i, l, 1)
rep(j, 0, 25)
tax1[i][j] = tax1[i + 1][j] + (st1[i] == ('a' + j)),
tax2[i][j] = tax2[i + 1][j] + (st2[i] == ('a' + j));
per(i, l, 1)
if (st2[i] == st1[l])
dp[l][i] = 0;
per(i, l, 1) chkmin(l, i, l, i + 1, 0);
/*	per(i, l, 2)
rep(j, 1, l) {
if (dp[i][j] != 0x3f3f3f3f) {
if (tax2[j][st1[i - 1] - 'a'] > tax1[i][st1[i - 1] - 'a'])
dp[i - 1][j] = std::min(dp[i - 1][j], dp[i][j] + 1);
for (int k = 1; k <= j - 1; k++)
if (st2[k] == st1[i - 1])
dp[i - 1][k] = std::min(dp[i - 1][k], dp[i][j]);
}
}*/
per(i, l - 1, 1)
per(j, l, 1) {
if (st1[i] == st2[j])
chkmin(i, j, i + 1, j + 1, 0);
//	dp[i][j] = std::min(dp[i][j], dp[i + 1][j + 1]);
if (tax2[j][st1[i] - 'a'] > tax1[i + 1][st1[i] - 'a'])
chkmin(i, j, i + 1, j, 1);
//	dp[i][j] = std::min(dp[i][j], dp[i + 1][j] + 1);
chkmin(i, j, i, j + 1, 0);
//dp[i][j] = std::min(dp[i][j], dp[i][j + 1]);
}//后缀min将n^3优化到n^2
printf("%d\n", dp[1][1]);
work(1, 1);
per(i, l, 1) if (pp[i] != pp[i + 1] && st2[pp[i]] == st1[i]) p[i] = 1, vis[pp[i]] = 1;
per(i, l, 1) {
if (p[i]) continue;
per(j, l, pp[i] + 1)
if (!vis[j] && st2[j] == st1[i]) {
pp[i] = j;
vis[j] = 1;
break;
}
}//找到最优情况下的匹配。
int poss = l + 1;
per(i, l, 1) {
if (pp[i] < poss) {
poss = pp[i];
continue;
}
printf("%d %d\n", pp[i] + ans[pp[i]], poss);
per(j, pp[i], poss)
ans[j]++;
}//按顺序从后面往前构造
}
return 0;
}

posted @ 2020-12-01 16:20  Tian-Xing  阅读(128)  评论(0编辑  收藏  举报