神DP POJ 1159 Palindrome

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

这道题原来见过,那时候没学DFS什么的,以为是搜索然后直接暴搜,但是说真的真是没有想到这题竟然是DP,那时候也没学DP就放弃了。。。

这道题的思路就是把整个问题分解成小问题,然后从下往上来求。。。

我们先设一个DP[N][N],它里面是每个i~j变成回文的最小添加量,也就是说我们可以看做DP后已经全部都是回文。

那么DP[1][N]就可以满足一个状态方程

if(STR[1] == STR[N]

I = 1,J = N;

DP[1][N] == DP[I+1][J-1] + 1   (STR[I] == STR[J])

                   DP[I+1][J]+1        (STR[I] != STR[J] && DP[I+1][J] < DP[I][J-1])

                   DP[I][J-1]+1        (STR[I] != STR[J] && DP[I+1][J] > DP[I][J-1])

 

但是如果我们这样写。。。。

 for(i = n-1;i >= 0;i--)
        {
            for(j = i+1;j < n;j++)
            {
                if(str[i] == str[j])
                dp[i][j] = dp[(i+1)][j-1];
                else
                dp[i][j] = (dp[(i+1)][j] < dp[(i)][j-1]?dp[i+1][j]:dp[i][j-1])+1;
            }
        }

由于数据量比较大 5000所以开数组的话会ME,这是我们就需要用滚动数组。

这段代码中时自底向上,而且只用了俩种i,所以

for(i = n-1;i >= 0;i--)
{
    for(j = i+1;j < n;j++)
    {
         if(str[i] == str[j])
         dp[i%2][j] = dp[(i+1)%2][j-1];
         else
         dp[i%2][j] = (dp[(i+1)%2][j] < dp[(i)%2][j-1]?dp[(i+1)%2][j]:dp[i%2][j-1])+1;
    }
}

 1  for(i = n-1;i >= 0;i--)
 2         {
 3             for(j = i+1;j < n;j++)
 4             {
 5                 if(str[i] == str[j])
 6                 dp[i][j] = dp[(i+1)][j-1];
 7                 else
 8                 dp[i][j] = (dp[(i+1)][j] < dp[(i)][j-1]?dp[i+1][j]:dp[i][j-1])+1;
 9             }
10         }

所以代码

View Code
#include <stdio.h>
#include <string.h>
#define N 5050
int dp[2][N];
int main()
{
    int n,i,j;

    char str[N];
    while(~scanf("%d",&n))
    {
        getchar();
        gets(str);
        memset(dp,0,sizeof(dp));
        for(i = n-1;i >= 0;i--)
        {
            for(j = i+1;j < n;j++)
            {
                if(str[i] == str[j])
                dp[i][j] = dp[(i+1)][j-1];
                else
                dp[i][j] = (dp[(i+1)][j] < dp[(i)][j-1]?dp[i+1][j]:dp[i][j-1])+1;
            }
        }
        printf("%d\n",dp[0][n-1]);
    }
    return 0;
}
posted @ 2012-08-21 21:04  某某。  阅读(158)  评论(0编辑  收藏  举报