题目的二分意思还是比较明显的,一开始还没有领悟到...
如果使用O(n^2)的lis, 肯定会超时的
其实对于一个string没有必要从开始的时候枚举它每一种的可能,这里用了逆向的思维,对于每一个string,逆向枚举它使用1个step所到达的string
然后二分的查找前面的string具体位置,
状态: dp[i] 表示前i个的最长阶梯
状态转移: dp[i] = max(dp[j]+1);
rst = max(dp[i], rst);
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
#define REPLACE 0
#define ADD 1
#define DELETE 2
#define OPERATOR 3
#define MAXCHAR 20
#define ALPHA 26
#define MAXN 25001
int dp[MAXN];
char str[MAXN][MAXCHAR], tar[MAXCHAR];
int binary_search(const int &idx)
{
int l(0), r(idx-1), m, rst;
while( l <= r ) {
m = (l+r)>>1;
if( !(rst = strcmp(tar, str[m])) ) {
return m;
}
else if( rst > 0 ) {
l = m+1;
}
else if( rst < 0 ) {
r = m-1;
}
}
return -1;
}
int change(const int &idx, const int &pos, const int &oper_type)
{
int pre, tar_idx(0);
if( REPLACE == oper_type ) {
for(int i = 0; i < ALPHA; i ++) {
strcpy(tar, str[idx]);
if( 'a'+i == str[idx][pos] ) {
continue;
}
tar[pos] = 'a'+i;
if( -1 != (pre = binary_search(idx)) ) {
dp[idx] = max(dp[idx], dp[pre]+1);
}
}
}
else if( ADD == oper_type ) {
for(int i = 0; i < ALPHA; i ++) {
tar_idx = 0;
for(int j = 0; j < pos; j ++) {
tar[tar_idx ++] = str[idx][j];
}
tar[tar_idx ++] = 'a'+i;
for(int j = pos; j < strlen(str[idx]); j ++) {
tar[tar_idx ++] = str[idx][j];
}
tar[tar_idx] = '\0';
if( -1 != ( pre = binary_search(idx) ) ) {
dp[idx] = max(dp[idx], dp[pre]+1);
}
}
}
else if( DELETE == oper_type ) {
tar_idx = 0;
for(int i = 0; i < pos; i ++) {
tar[tar_idx ++] = str[idx][i];
}
for(int i = pos+1; i < strlen(str[idx]); i ++) {
tar[tar_idx ++] = str[idx][i];
}
tar[tar_idx] = '\0';
if( -1 != (pre = binary_search(idx)) ) {
dp[idx] = max(dp[idx], dp[pre]+1);
}
}
return dp[idx];
}
int main(int argc, char const *argv[])
{
#ifndef ONLINE_JUDGE
freopen("test.in", "r", stdin);
#endif
int idx(0), pos, rst(1);
while( ~scanf("%s", str[idx]) ) { idx ++; }
memset(dp, 0, sizeof(int)*(idx+1));
for(int i = 1; i < idx; i ++) {
for(int j = 0; j < strlen(str[i]); j ++) {
for(int k = 0; k < OPERATOR; k ++) {
rst = max(rst, change(i, j, k)+1);
}
}
}
printf("%d\n", rst);
return 0;
}
uva_10029 - Edit Step Ladders( LIS )
最新推荐文章于 2017-08-14 11:16:00 发布
本文介绍了一种解决字符串阶梯问题的方法,通过逆向思维和二分查找优化了最长递增子序列(LIS)算法,实现了高效的求解过程。
118

被折叠的 条评论
为什么被折叠?



