lightoj-1044 - Palindrome Partitioning(区间dp)

1044 - Palindrome Partitioning
PDF (English) Statistics Forum
Time Limit: 1 second(s) Memory Limit: 32 MB
A palindrome partition is the partitioning of a string such that each separate substring is a palindrome.

For example, the string "ABACABA" could be partitioned in several different ways, such as {"A","B","A","C","A","B","A"}, {"A","BACAB","A"}, {"ABA","C","ABA"}, or {"ABACABA"}, among others.

You are given a string s. Return the minimum possible number of substrings in a palindrome partition of s.

Input
Input starts with an integer T (≤ 40), denoting the number of test cases.

Each case begins with a non-empty string s of uppercase letters with length no more than 1000.

Output
For each case of input you have to print the case number and the desired result.

Sample Input
Output for Sample Input
3
AAAA
ABCDEFGH
QWERTYTREWQWERT
Case 1: 1
Case 2: 8
Case 3: 5

解题:预处理好回文字符串,然后dfs。

但dp[l][r] = min(dp[l][r],dfs(l,i)+dfs(i+1,r)); 这种的dfs会爆

仔细分析下会发现 (回文字符串+一串字母) + 一串字母 跟 回文字符串+(一串字母+一串字母) 的情况是一样, 所以可能省略掉前面dfs(l,i)的情况

直接  if(judge[l][i])  dp[l][r] = min(dp[l][r],1+dfs(i+1,r));

#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
using namespace std;

const int inf = 1e9;
int T,len;
char str[1100];
int dp[1100][1100];
bool judge[1100][1100];

void init(){
    memset(judge,false,sizeof(judge));
    memset(dp,-1,sizeof(dp));    

    for(int i=0;i<len;i++){
        for(int j=i;j<len;j++){
            int flag = 0;
            for(int z=i;z<=(i+j)/2;z++){
                if(str[z]!=str[j-(z-i)]){
                    flag = 1;break;
                }
            }
            if(flag == 0) judge[i][j] = true;
        }
    }
}

int dfs(int l,int r){

    if(judge[l][r]){
        dp[l][r] = 1;
        return 1;
    }
    if(dp[l][r]!=-1) return dp[l][r];

    dp[l][r] = inf;
    for(int i=l;i<r;i++){    

        if(judge[l][i])
            dp[l][r] = min(dp[l][r],1+dfs(i+1,r));
        //dp[l][r] = min(dp[l][r],dfs(l,i)+dfs(i+1,r));
    }
    return dp[l][r];
}

int main(){

    scanf("%d",&T);
    for(int t=1;t<=T;t++){

        scanf("%s",str);
        len = strlen(str);
        init();
        printf("Case %d: %d\n",t,dfs(0,len-1));
    }

    return 0;
}

时间: 2024-12-25 12:33:45

lightoj-1044 - Palindrome Partitioning(区间dp)的相关文章

Lightoj 1044 - Palindrome Partitioning (DP)

题目链接: Lightoj  1044 - Palindrome Partitioning 题目描述: 给一个字符串,问至少分割多少次?分割出来的子串都是回文串. 解题思路: 先把给定串的所有子串是不是回文串处理出来,然后用dp[i] 表示 从起点到串i的位置的最少分割次数,然后结合处理出来的回文串转移一下即可! 还是好蠢哦!自己竟然感觉是一个区间DP,但是n又那么大,完全不是区间DP的作风啊! 1 #include <cmath> 2 #include <cstdio> 3 #i

LightOJ 1044 Palindrome Partitioning(简单字符串DP)

A palindrome partition is the partitioning of a string such that each separate substring is a palindrome. For example, the string "ABACABA" could be partitioned in several different ways, such as {"A","B","A","

HDU 4632 Palindrome subsequence(区间dp,回文串,字符处理)

题目 参考自博客:http://blog.csdn.net/u011498819/article/details/38356675 题意:查找这样的子回文字符串(未必连续,但是有从左向右的顺序)个数. 简单的区间dp,哎,以为很神奇的东西,其实也是dp,只是参数改为区间,没做过此类型的题,想不到用dp,以后就 知道了,若已经知道[0,i],推[0,i+1], 显然还要从i+1 处往回找,dp方程也简单: dp[j][i]=(dp[j+1][i]+dp[j][i-1]+10007-dp[j+1][

1044 - Palindrome Partitioning(区间DP)

题目大意: 给你一个字符串,问这个字符串最少有多少个回文串. 区间DP直接搞 #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #include<cmath> #include<queue> #include<vector> #include<map> using namespace std; typedef lo

LightOJ 1422 Halloween Costumes 区间dp

题意:给你n天需要穿的衣服的样式,每次可以套着穿衣服,脱掉的衣服就不能再穿了,问至少要带多少条衣服才能参加所有宴会 思路:dp[i][j]代表i-j天最少要带的衣服 从后向前dp 区间从大到小 更新dp[i][j]时有两种情况 考虑第i天穿的衣服 1:第i天穿的衣服在之后不再穿了 那么 dp[i][j]=dp[i+1][j]+1; 2:第i天穿的衣服与i+1到j的某一天共用,那么dp[i][j]=min(dp[i][j],dp[i+1][k-1],dp[k][j]),前提是第i天和第k天需要的礼

POJ 3280 Cheapest Palindrome(区间DP求改成回文串的最小花费)

题目链接:http://poj.org/problem?id=3280 题目大意:给你一个字符串,你可以删除或者增加任意字符,对应有相应的花费,让你通过这些操作使得字符串变为回文串,求最小花费.解题思路:比较简单的区间DP,令dp[i][j]表示使[i,j]回文的最小花费.则得到状态转移方程: dp[i][j]=min(dp[i][j],min(add[str[i]-'a'],del[str[i]-'a'])+dp[i+1][j]); dp[i][j]=min(dp[i][j],min(add[

Light oj 1044 - Palindrome Partitioning(区间dp)

题目链接:http://lightoj.com/volume_showproblem.php?problem=1044 dp[i][j]表示i到j直接的最小回文区间个数,直接看代码 1 #include <bits/stdc++.h> 2 using namespace std; 3 const int N = 1e3 + 5; 4 int dp[N][N], inf = 1e9; 5 char str[N]; 6 bool judge(int l, int r) { 7 for(int i

HDU 4632 Palindrome subsequence (区间dp 容斥定理)

Palindrome subsequence Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/65535 K (Java/Others) Total Submission(s): 2610    Accepted Submission(s): 1050 Problem Description In mathematics, a subsequence is a sequence that can be derived

LightOJ 1422 Halloween Costumes (区间dp 好题)

1422 - Halloween Costumes PDF (English) Statistics Forum Time Limit: 2 second(s) Memory Limit: 32 MB Gappu has a very busy weekend ahead of him. Because, nextweekend is Halloween, and he is planning to attend as many parties as he can.Since it's Hall