UVA - 11584 划分字符串的回文串子串; 简单dp

/**

链接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=34398

UVA - 11584 划分字符串的回文串子串; 简单dp

题目大意:

给一个字符串, 要求把它分割成若干个子串,使得每个子串都是回文串。问最少可以分割成多少个。

定义:dp[i]表示前0~i内的字符串划分成的最小回文串个数;

dp[i] = min(dp[j]+1 | j+1~i是回文串);

先预处理flag[i][j]表示以i~j内的字符串为回文串;

可以通过遍历字符串中心来处理;

*/

#include<iostream>

#include<cstring>

#include<cstdio>

#include<string>

#include<set>

#include<algorithm>

#include<vector>

#include<map>

#include<queue>

#include<cmath>

#include<cctype>

#include<stack>

#include<iomanip>

using namespace std;

typedef pair<int,int> pr;

const int maxn = 1005;

const int inf = 0x3f3f3f3f;

char s[maxn];

bool flag[maxn][maxn];

int dp[maxn], ls;

void dfs(int i,int j)

{

    if(i==0||j>ls) return ;

    if(s[i]==s[j]){

        flag[i][j] = true;

        dfs(i-1,j+1);

    }

}

int main()

{

    int T;

    cin>>T;

    while(T--)

    {

        scanf("%s",s+1);

        ls = strlen(s+1);

  //      cout<<"ls = "<<ls<<endl;

        memset(flag,false,sizeof flag);

        for(int i = 1; i <= ls; i++){

            flag[i][i] = true;

            dfs(i,i+1);//令i为偶数回文串中心的左边那个;

            dfs(i-1,i+1); //令i为奇数回文串中心的中间那个;

         //   dfs(i-1,i);  不需要令i为偶数回文串中心的右边那个,因为已经令i为偶数回文串中心的左边那个;中包含了;

        }/*

        for(int i = 1; i <= ls; i++){

            for(int j = 1; j <= ls; j++){

                cout<<"i = "<<i<<"j = "<<j<<"flag[i][j] = "<<flag[i][j]<<endl;

            }

        }*/

        for(int i = 1; i <= ls; i++) dp[i] = inf;

        dp[0] = 0;

        for(int i = 1; i <= ls; i++){

            for(int j = 0; j < i; j++){

                if(flag[j+1][i])

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

            }

        }

 //       for(int i = 1; i <= ls; i++) cout<<"dp[i] = "<<dp[i]<<endl;

        printf("%d\n",dp[ls]);

    }

    return 0;

}

时间: 2024-10-23 20:24:38

UVA - 11584 划分字符串的回文串子串; 简单dp的相关文章

UVa 401 Palindromes(字符串,回文)

 Palindromes  A regular palindrome is a string of numbers or letters that is the same forward as backward. For example, the string "ABCDEDCBA" is a palindrome because it is the same when the string is read from left to right as when the string i

UVa 10617 Again Palindrome(回文串区间DP)

UVa 10617 Again Palindrome(经典回文串区间DP) 题意: 给定一个字符串s,对s进行删除操作,使得剩下的子串是回文字符串,问最多有多少种这种子串. 思路: 涉及到回文字符串,首先要想到的肯定是区间DP,如何写出状态转移方程? 直接从题意切入:dp[i, j]表示区间[i, j]最多有多少个这样的子串. 1. s[i] == s[j] 去掉s[i],则一个子问题就是dp[i+1, j]; 去掉s[j],另一个子问题就是dp[i, j-1]; 显然这两个子问题是会有重叠的,

[程序员代码面试指南]字符串问题-回文最少分割数(DP)

问题描述 给定一个字符串,输出把它全部切成回文子串的最小分割数. 例:str="ACDCDCDAD",输出2. 解题思路 DP 存储结构 dp数组dp[len+1],dp[i]表示子串str[I:len]至少需要切割几次,才能都切割成回文串.对应的,循环从右至左进行. 注意 dp[i]的含义完全可以做对称更改,循环也变为从前向后即可. 此外,为了保证int cutTime=dp[j+1]+1;//句的顺利执行,且dp[len-1]=0,palStr=true.dp数组多开一位,并初始化

UVa11404Palindromic Subsequence(最大回文串,区间DP)

Description A Subsequence is a sequence obtained by deleting zero or more characters in a string. A Palindrome is a string which when read from left to right, reads same as when read from right to left. Given a string, find the longest palindromic su

最长双回文串(模板+dp)

题目链接 1 #include <bits/stdc++.h> 2 using namespace std; 3 typedef long long ll; 4 inline ll read(){ 5 int x = 0, f = 1; char ch = getchar(); 6 while(ch > '9' || ch < '0'){if (ch == '-') f = -1; ch = getchar();} 7 while(ch >= '0' && c

回文串+回溯法 URAL 1635 Mnemonics and Palindromes

题目传送门 1 /* 2 题意:给出一个长为n的仅由小写英文字母组成的字符串,求它的回文串划分的元素的最小个数,并按顺序输出此划分方案 3 回文串+回溯:dp[i] 表示前i+1个字符(从0开始)最少需要划分的数量,最大值是i+1,即单个回文串: 4 之前设置ok[j][j+i] 判断从j到j+i的字符是否为回文串(注意两个for的顺序,为满足ok[j][j+i] = ok[j+1][j+i-1]) 5 最后枚举找到最优划分点,用pre[i]记录前一个位置,print函数 输出空格 6 */ 7

Uva 11584,划分成回文串

题目链接:https://uva.onlinejudge.org/external/115/11584.pdf 题意: 一个字符串,将它划分一下,使得每个串都是回文串,求最少的回文串个数. 分析: d(i)到第 i 个字符时的最优解(即最少划分为几个回文串),就有方程  d(i) = min(d(j)) + 1;(其中s[j+1,i]要是回文串). 这样一来,枚举就是O(n^2)的复杂度,如果按照普通的判断s[j+1,i]是否是回文串,时间复杂度为O(n^3);先用O(n^2)的复杂度预处理is

Valid Palindrome ——判断字符串是否为回文串

本文是在学习中的总结,欢迎转载但请注明出处:http://blog.csdn.net/pistolove/article/details/41488377 Valid Palindrome Given a string, determine if it is a palindrome, considering only alphanumeric characters and ignoring cases. For example, "A man, a plan, a canal: Panama&

例题9-7 划分成回文串 UVa11584

1.题目描述:点击打开链接 2.解题思路:本题要求划分回文串,且个数尽可能的少.可以用动态规划解决.先提前判断i~j是否构成回文串,时间复杂度是O(N^2),然后定义d(i)表示0~i-1划分成的回文串的最小个数.则状态转移方程为: d(i)=min(d(i),d(j)+1)(s[j...i]是回文串) 上式中,d(i)的初始值是i,这样每次判断只需要O(1)的时间,总时间复杂度是O(N^2).当然,判断回文串的过程可以和状态转移相结合,细节请参考第二份代码. 3.代码: #define _CR