zoukankan      html  css  js  c++  java
  • 神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;
    }
  • 相关阅读:
    C# 后台调用webApi
    WebApi传参详解
    网络爬虫字体解密
    单元测试的简单实用
    JQuery中$.ajax()方法参数详解
    vscode HTML标签换行问题
    C#基础之Assembly 当前项目的程序集GetAssemblies
    RedisHelper
    vue setTimeout 和 this.$nextTick,BMap api
    excel 导出 OpenXml
  • 原文地址:https://www.cnblogs.com/0803yijia/p/2649727.html
Copyright © 2011-2022 走看看