题目的二分意思还是比较明显的,一开始还没有领悟到... 如果使用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; }