给定一个字符串,问最少添加多少个字符可以使得这个字符串变成回文串
if(str[i]==str[j]) dp[i][j] = dp[i+1][j-1]
else dp[i][j] = min(dp[i][j-1],dp[i+1][j]);
可以看出,dp[i][j] 要么是从dp[i+1][] 这个状态转移而来,要么是从dp[i][j-1]这个状态转移而来(这个只要从小到大枚举j即可)
所以我们可以用滚动数组来压缩空间
1 #pragma warning(disable:4996) 2 #pragma comment(linker, "/STACK:1024000000,1024000000") 3 #include <stdio.h> 4 #include <string.h> 5 #include <time.h> 6 #include <math.h> 7 #include <map> 8 #include <set> 9 #include <queue> 10 #include <stack> 11 #include <vector> 12 #include <bitset> 13 #include <algorithm> 14 #include <iostream> 15 #include <string> 16 #include <functional> 17 #include <unordered_map> 18 typedef __int64 LL; 19 const int INF = 999999999; 20 21 /* 22 23 if(str[i]==str[j]) 24 dp[i][j] = dp[i+1][j-1] 25 else 26 dp[i][j] = min(dp[i][j-1],dp[i+1][j]) 27 */ 28 const int N = 5000 + 10; 29 int dp[2][N]; 30 char str[N]; 31 32 33 int main() 34 { 35 int n; 36 while (scanf("%d%s", &n, str+1) != EOF) 37 { 38 memset(dp, 0, sizeof(dp)); 39 for (int i = n; i >= 1;--i) 40 { 41 for (int j = i + 1;j <= n;++j) 42 { 43 if (str[i] == str[j]) 44 dp[i%2][j] = dp[(i + 1)%2][j - 1]; 45 else 46 dp[i%2][j] = std::min(dp[(i + 1)%2][j], dp[i%2][j - 1])+1; 47 } 48 } 49 printf("%d\n", dp[1][n]); 50 } 51 return 0; 52 }
时间: 2024-10-13 01:00:40