UVA - 10029 Edit Step Ladders

题目大意:给出若干个按照字典序排列的字符串,每两个字符串之间可以存在一个梯度,也可不存在,所谓梯度就是指前一个字符串同过改变、删除或填加一个字符,是转化后的字符串等于后面一个字符串,问,在所给出的若干个字符串中最多能连续通过梯度连接多少个字符串,输出最大值。


解题思路:类似与LIS,可是用o(n^2)的算法却超时, 可以用二分的方法在前面的字符串中找匹配,给出的字符串是按照字典序排列的,这样的话等于是一个有序的序列,完全可以将当前前字符串的所有变换字符串去用二分搜索出来。


#include <cstdio>
#include <cstring>
char word[25005][20];
int len[25005];

bool judge_1(int x, int y) {
	int cnt = 0;
	for (int i = 0; i < len[x]; i++)
		if (word[x][i] != word[y][i])
			cnt++;
	if (cnt != 1)
		return false;
	return true;
}

bool judge_2(int x, int y) {
	int cnt = 0;
	for (int i = 0, j = 0; i < len[x]; i++)
		word[x][i] != word[y][j] ? cnt++ : j++;
	if (cnt != 1)
		return false;
	return true;
}

int main() {
	int n = 0, DP[25005] = {0}, max = 0;
	while (gets(word[n])) {
		len[n] = strlen(word[n]);
		n++;
	}

	for (int i = 0; i < n; i++) {
		DP[i] = 1;
		for (int j = 0; j < i; j++) {
			if (len[i] == len[j] && judge_1(i, j) && DP[j] >= DP[i])
				DP[i] = DP[j] + 1;
			else if(len[i] == len[j] + 1 && judge_2(i, j) && DP[j] >= DP[i])
				DP[i] = DP[j] + 1;
			else if(len[i] == len[j] - 1 && judge_2(j, i) && DP[j] >= DP[i])
				DP[i] = DP[j] + 1;
		}
		if (DP[i] > max)
			max = DP[i];
	}
	printf("%d\n", max);
	return 0;
}


你可能感兴趣的:(UVA - 10029 Edit Step Ladders)