leetcode:Palindrome Partitioning II

谨遵学长教导,开始刷算法题,从leetcode开始做起。可惜第一次就碰到了两个dp的问题Palindrome Partitioning II。。。委屈第一次搞了半天,感觉像是可以建模为最短路径问题,思路不清晰,乱写竟然通过了judge small,在judge large的时候,最后一个测试例子没有通过,显示超时。不懂为什么,后来google了一下,发现原来是判断是不是回文也要用dp,艾。。后来就没有再管了。今天又重新写了,也做了写注释,感觉思路清晰多了,测试,全部通过。

题目如下:

Given a string s, partition s such that every substring of the partition is a palindrome.

Return the minimum cuts needed for a palindrome partitioning of s.

For example, given s = "aab",
Return 1 since the palindrome partitioning ["aa","b"] could be produced using 1 cut.

代码如下:
int minCut(string s)
	{
		/*
		在s的len个字符之间放len-1个木板,并且在两端个放一个,这样就有len+1个木板
		*/
		int len=s.length();
		int BIG=2*len;
		int num_line=len+1;
		//表明两个木板之间substr是否为回文,如果有则代表它两端的木板可以直接相连,
		//否则,代表它两端的木板必须通过其他木板相连,也就是不相连
		//将这些木板作为节点,上面的连接关系作为边,建立图
		vector<int> isPalindrome(num_line*num_line);
		/*
		if s[i]==s[j]
			f(i,j)=f(i+1,j-1)
		else
			f(i,j)=0
		*/
		for(int l=1;l<=len;l++)//两个木板之间有多少个字符
		{
			for (int i=0;i+l<num_line;i++)//从第0个木板开始,i+l为木板的序号
			{
				if (l==1)
				{
					isPalindrome[i*num_line+(i+l)]=1;
				}
				else if(l==2)
				{
					if (s[i]==s[i+l-1])
						isPalindrome[i*num_line+(i+l)]=1;
					else
						isPalindrome[i*num_line+(i+l)]=BIG;
				}
				else
				{
					if (s[i]==s[i+l-1])
						isPalindrome[i*num_line+(i+l)]=isPalindrome[(i+1)*num_line+(i+l-1)];
					else
						isPalindrome[i*num_line+(i+l)]=BIG;
				}
			}
		}
		/*
		找第0个木板与最后一个木板之间的最短距离
		*/
		vector<int> dist(num_line);
		vector<bool> labeled(num_line);
		for(int i=0;i<num_line;i++)
		{
			dist[i]=BIG;
			labeled[i]=false;
		}
		dist[0]=0;
		labeled[0]=true;
		int current_line=0;
		for(int i=1;i<num_line;i++)
		{	
			for(int d=current_line+1;d<num_line;d++)//对所有的相邻(在图中)的木板
			{
				if(!labeled[d])
				{
					if (dist[current_line]+isPalindrome[current_line*num_line+d]<dist[d])
					{
						dist[d]=dist[current_line]+isPalindrome[current_line*num_line+d];
					}
				}
			}
			int mindist=BIG;
			int minindex=-1;
			for(int i=0;i<num_line;i++)
			{
				if(!labeled[i])
				{
					if(mindist>dist[i])
					{
						minindex=i;
						mindist=dist[i];
					}
				}
			}
			current_line=minindex;
			labeled[minindex]=true;
		}

		return dist[num_line-1]-1;
	}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值