poj1159 Palindrome 区间DP

题目链接:http://poj.org/problem?id=1159

思路1:

区间DP思想:

定义dp[i][j]表示从区间(i,j)之间需要增加的字符的最少数量,那么如果s[i]==s[j],那么dp[i][j]=dp[i-1][j-1]

否则dp[i][j]=min(dp[i+1][j]+1,dp[i][j-1]+1);

如果直接DP,需要开5001*5001的数组,用int会超内存

用short int 能过;

代码如下:

 1 #include<iostream>
 2 #include<cstdlib>
 3 #include<cstdio>
 4 #include<cstring>
 5 #include<string>
 6 using namespace std;
 7 short int  dp[5001][5001];
 8 string s;
 9 int main()
10 {
11         int n;
12         while(scanf("%d",&n)!=EOF)
13         {
14                 memset(dp,0,sizeof(dp));
15                cin>>s;
16                for(int j=0;j<n;j++)
17                        for(int i=j-1;i>=0;i--)
18                                if(s[i]==s[j])
19                                {
20                                  dp[i][j]=dp[i+1][j-1];
21                                }
22                                else
23                                {
24                                  dp[i][j]=min(dp[i][j-1]+1,dp[i+1][j]+1);
25                                }
26                cout<<dp[0][n-1]<<endl;
27         }
28         return 0;
29 }
View Code

但是定义short int 不是常规的做法;

常规思路:LCS+滚动数组

思路:

很容易想到需要增加的字符长度等于字符串s的长度-字符串s与它的逆串s'的最长公共字串的长度

然后问题就转化为LCS问题,简单吧

只要在处理时用滚动数组将空间消耗从n*n降为n

至于滚动数组,我们很容易知道dp[i]与dp[i-2]无关,所以只要开个2*n的空间即可,具体见代码:

 1 #include<iostream>
 2 #include<cstdlib>
 3 #include<cstdio>
 4 #include<cstring>
 5 using namespace std;
 6 int dp[2][5010];
 7 char s1[5010];
 8 char s2[5010];
 9 int main()
10 {
11        int n;
12        while(scanf("%d",&n)!=EOF)
13        {
14                memset(dp,0,sizeof(dp));
15                cin>>s1;
16                 int j=0;
17                for(int i=n-1; i >= 0; i--) 
18                s2[j++] = s1[i];
19                for(int i=0;i<n;i++)
20                        for(int j=0;j<n;j++)
21                               if(s1[i]==s2[j])
22                                       dp[(i+1)%2][j+1]=dp[i%2][j]+1;
23                                       else dp[(i+1)%2][j+1]=max(dp[(i+1)%2][j],dp[i%2][j+1]);
24                cout<<n-dp[n%2][n]<<endl;
25 
26 
27        }
28        return 0;
29 }
View Code

原文地址:https://www.cnblogs.com/xiaozhuyang/p/poj1159.html