hdoj 1513 Palindrome 【LCS】+【滚动数组】

来源:互联网 发布:26岁零基础转行大数据 编辑:程序博客网 时间:2024/05/22 00:23

Palindrome

Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 3276    Accepted Submission(s): 1134


Problem Description
A palindrome is a symmetrical string, that is, a string read identically from left to right as well as from right to left. You are to write a program which, given a string, determines the minimal number of characters to be inserted into the string in order to obtain a palindrome.

As an example, by inserting 2 characters, the string "Ab3bd" can be transformed into a palindrome ("dAb3bAd" or "Adb3bdA"). However, inserting fewer than 2 characters does not produce a palindrome.
 

Input
Your program is to read from standard input. The first line contains one integer: the length of the input string N, 3 <= N <= 5000. The second line contains one string with length N. The string is formed from uppercase letters from 'A' to 'Z', lowercase letters from 'a' to 'z' and digits from '0' to '9'. Uppercase and lowercase letters are to be considered distinct.
 

Output
Your program is to write to standard output. The first line contains one integer, which is the desired minimal number.
 

Sample Input
5Ab3bd
 

Sample Output
2
#include<cstdio>#include<cstring>#include<iostream>#include<algorithm>#include<cmath>using namespace std;char str[5010];char s[5010];int dp[2][5010];  //dp[5010][5010], int main(){int n;    while(~scanf("%d",&n))    {         int i,j;        scanf("%s",str);        for(i=0;i<n;i++)        {        //scanf("%c",&str[i]);//Output Limit Exceeded        s[n-1-i]=str[i];        }    memset(dp, 0, sizeof(dp));//dp的无后效性,可以优化内存,运用滚动数组         for(i = 1; i <= n; i ++){            for(j = 1; j <= n; j++){                if(str[i-1] == s[j-1]) dp[i%2][j] = dp[(i-1)%2][j-1] + 1;//dp[i][j]=dp[i-1][j-i]+1;                 else dp[i%2][j] = max(dp[(i-1)%2][j], dp[i%2][j-1]);  // dp[i][j] = max(dp[i-1][j], dp[i][j-1])            }        }        printf("%d\n", n-dp[n%2][n]);  //n-dp[n][n]     }return 0;} 
无后效性:
例如,对于这道单词接龙的题目,每个单词最多用两次。
那么“当前接到的单词”就不能概括整个“历史”,因为同样是接到的这个单词,以前考虑过的单词究竟是用过
没有,用过多少次,将同样影响今后的发展,而单一的状态参量无法概括这些信息。如果把这些信息加到状态
参量中,状态太多(指数级),动态规划也没有多大意义。

如果影响历史的信息并不多,我们可以通过升维的方法让我们的状态具有无后效性,
所以我们在思考状态的时候,指导思想就是“简洁而又完全的概括历史”


0 0