• UVA11584


    题目大意:见刘汝佳《算法竞赛入门经典(第2版)》P275

    解题思路:

      有点类似最长上升子序列的一个DP问题。

      设 dp[i] 为对于字符串 s[1,...,i] 的最少回文串数。转移方程为:dp[i] = min{dp[j] + 1 | j<i,s[j+1,...,i]为回文串}。那么问题就是如何判断某个字符串子串是不是回文串。本来DP这部分的时间复杂度就是O(n^2),如果再对于每一个“状态”加上一个O(n)的循环来判断是否为回文数的话,时间复杂度就变成 O(n^3)带入数据范围一算不难发现会超时,那么我们只能预处理判断的这部分。请看程序及注释。

    AC代码:

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstring>
     4 #include <algorithm>
     5 
     6 using namespace std;
     7 const int maxn=1000+3,inf=0x7fffffff;
     8 char inp[maxn];
     9 bool is_pp[maxn][maxn];
    10 int dp[maxn];
    11 int main()
    12 {
    13     int n;
    14     scanf("%d",&n);
    15     while(n--){
    16         memset(is_pp,false,sizeof(is_pp));
    17         scanf("%s",inp+1);
    18         int len=strlen(inp+1);
    19 //**************************************************************************
    20 //预处理部分
    21         for(int i=1;i<=len;i++){    //枚举中点
    22             is_pp[i][i]=true;       //单个字符肯定是回文串
    23             for(int j=1;;j++){      //向左右伸展
    24                 if(i-j<1||i+j>len) break;
    25                 if(inp[i-j]==inp[i+j])  is_pp[i-j][i+j]=true;   
    26                 else    break;      //一旦发现左右不等,当即退出
    27             }
    28             if(i+1<=len&&inp[i]==inp[i+1]){//上面一个循环处理的是字符串长度为奇数的部分,这个循环处理的是字符串长度为偶数的部分
    29                 is_pp[i][i+1]=true;
    30                 for(int j=1;;j++){
    31                     if(i-j<1||i+j+1>len)   break;
    32                     if(inp[i-j]==inp[i+j+1])    is_pp[i-j][i+j+1]=true;
    33                     else    break;
    34                 }
    35             }
    36         }
    37 //*************************************************************************
    38         dp[0]=0;
    39         for(int i=1;i<=len;i++){
    40             dp[i]=inf;
    41             for(int j=0;j<i;j++){
    42                 if(is_pp[j+1][i])
    43                     dp[i]=min(dp[i],dp[j]+1);
    44             }
    45         }
    46         printf("%d
    ",dp[len]);
    47     }
    48     return 0;
    49 }
    “这些年我一直提醒自己一件事情,千万不要自己感动自己。大部分人看似的努力,不过是愚蠢导致的。什么熬夜看书到天亮,连续几天只睡几小时,多久没放假了,如果这些东西也值得夸耀,那么富士康流水线上任何一个人都比你努力多了。人难免天生有自怜的情绪,唯有时刻保持清醒,才能看清真正的价值在哪里。”
  • 相关阅读:
    maven 3.2.5 的安装,部署和实例
    Java8 stream操作toMap的key重复问题
    Jenkins配置定时任务注意点
    npm install提示node-sass错误
    centos 使用docker 安装 teamcity
    centos 不能连接外网,使用本地yum源安装软件
    git添加本地代码到远程仓库
    mysql 新建外网用户 和只读用户
    mysql 删除重复数据保留最新一条
    批量删除redis缓存
  • 原文地址:https://www.cnblogs.com/Blogggggg/p/7652832.html
Copyright © 2020-2023  润新知