hdu 1513 Palindrome

来源:互联网 发布:知柏地黄丸吃多少粒 编辑:程序博客网 时间:2024/06/10 11:00

        hdu 1513 Palindrome

        求出字符串的顺序和逆序的最长公共子序列的长度, 插入数 = 字符串的长度 - 最长公共子序列长度。

        这道题给出的是最长可以5000的字符串长度哦,假如使用一般的方法来开个二维数组,那么内存会不够的啦, 那么就用滚动数组吧。

        这道题需要的是最长公共子序列的长度, 那么可以放弃一些之前的状态, 因为只需要dp[n][m]啦。

        滚动数组就是重复利用较小的空间来存放当前需要的状态啦, 比如:求斐波那契数f(8)的值是多少?

int a[3];for (int i = 2; i < 9; i++) {    a[i%3] = a[(i-1)%3] + a[(i-2)%3];}

         上面吧a数组重复利用了,因为不需要保存之前的状态。

         而求最长公共子序列需要dp[i-1][j-1]的状态, 那么我们只需要一个dp[2][MAX]的空间就能保存和推得当前状态了。

#include <stdio.h>#include <string.h>#define MAX 5005int dp[2][MAX];char str[MAX], revStr[MAX];int n;inline int max(int a, int b) {return a > b ? a : b;}int lcs(char* strA, char* strB) {int i, j;memset(dp, 0, sizeof(dp));for (i = 1; i <= n; i++) {for (j = 1; j <= n; j++) {if (strA[i] == strB[j]) {dp[i&1][j] = dp[(i - 1)&1][j - 1] + 1;} else {dp[i&1][j] = max(dp[(i - 1)&1][j], dp[i&1][j - 1]);}}}return dp[n&1][n];}int main() {int i ,lcsLen;while (scanf("%d%s", &n, &str[1]) != EOF) {for (i = 1; i <= n; i++) {revStr[i] = str[n - i + 1];}revStr[i] = '\0';lcsLen = lcs(str, revStr);printf("%d\n", n - lcsLen); }return 0;} 
原创粉丝点击