#include<cstdio> #include<cstring> #include<cstdlib> #define MAXN 5005 #define max(a, b) ( a > b ? a : b) short f[MAXN][MAXN], len; char a[MAXN], b[MAXN]; void rev() { for( int i = len, j = 1; i >= 1; i --, j ++) { b[j] = a[i]; } } void dp() { memset( f, 0, sizeof f); for( int i = 1; i <= len; i ++) for( int j = 1; j <= len; j ++) { if( a[i] == b[j]) f[i][j] = f[i - 1][j - 1] + 1; else f[i][j] = max( f[i - 1][j], f[i][j - 1]); } } int main() { while( scanf( "%d", &len) != EOF) { scanf( "%s", a + 1); rev(); dp(); printf( "%d\n", len - f[len][len]); } return 0; }
题目问的是最少几步可以将原串变成回文串,其实就是原串长度减去原串与逆置串最长
公共子序列的长度。这里int超内存,用short来存储。还有另一个就是用滚动数组,这里不是
很明白...
#include<stdio.h> #include<string.h> #include<stdlib.h> const int MAXN = 5005; int dp[MAXN], prei, prej, len; char a[MAXN]; int max(int a, int b) {return a > b ? a : b;} int main() { int i, j; while(scanf("%d", &len) != EOF) { memset(dp, 0, sizeof(dp)); scanf("%s", a); prej = prei = 0; for(i = 0; i < len; ++ i) { prej = 0; for(j = 0; j < len; ++ j) { prei = dp[j + 1]; if(a[i] == a[len - j - 1]) dp[j + 1] = prej + 1; else dp[j + 1] = max(dp[j + 1], dp[j]); prej = prei; } } printf("%d\n", len - dp[len]); } return 0; }