一、问题描述
给定一个字符串s,分区s使分区的每个子字符串都是回文。返回s的回文分区所需的最小切割。
【例子】输入: "aab"
输出: 1
回文分区[“aa”,“b”]最小可以使用1次剪切生成
二、问题分析
本题主要涉及到两个子问题:1)如何描述该动态规划的状态转移方程? 2)如何判断回文?
显然这两个子问题需要回归到同一个代码情景中,即:需要找到一个统一的方法,让这两个子问题都能得到回归。
【如何判断回文】
如果judge[i][j]=true,表示字符串从位置i到位置j是回文,那么判断条件可以写成:if( s[i]==s[j]&&judge[i+1][j-1] ) judge[i][j]=true
【如何描述转移方程】
回归到判断回文的代码情景,这里 i<= j < n; 用f(i)表示从i到n之间的最小cut数,则状态转移方程可写成:
f(i) = min( f( i ),f( j +1 ) +1 ) 即:要么cut,要么不cut,总体效果是cut值最小
三、解题算法
/***********************************************************
Author:tmw
date:2018-5-23
************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
#define min(a,b) (a<b?a:b)
int minCut(char* s)
{
//定义回文判断的二维bool型数组,并赋初值
int n=strlen(s);
bool** judge = (bool**)malloc(n*sizeof(bool*));
int i,j;
for( i=0; i<n; i++ )
judge[i] = (bool*)malloc(n*sizeof(bool));
for( i=0; i<n; i++ )
for( j=0; j<n; j++ )
judge[i][j] = false;
//定义动态规划状态转移函数存储空间,并赋初值
int* f = (int*)malloc((n+1)*sizeof(int));
//最糟糕的情况,是每个从i位置到n-1位置都要cut一遍
for( i=0; i<=n; i++ )
f[i] = n-i-1; //f[n]=-1 为了防止当"bb"这种情况时,f[0]=1
for( i=n-1; i>=0; i-- )
{
for( j=i; j<n; j++ )
{
//i位置到j位置的回文判断
if( s[i] == s[j] && ( j-i<=1 || judge[i+1][j-1]) )
{
judge[i][j] = true;
f[i] = min(f[i],1+f[j+1]);
}
}
}
return f[0];
}
四、执行结果
accept
梦想还是要有的,万一实现了呢~~~~ヾ(◍°∇°◍)ノ゙~~~