一、问题描述
给定一个字符串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值最小
扫描二维码关注公众号,回复:
1478764 查看本文章
三、解题算法
/*********************************************************** 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
梦想还是要有的,万一实现了呢~~~~ヾ(◍°∇°◍)ノ゙~~~