算法导论之动态规划 字符串拆分问题

Posted 童话的守望者

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了算法导论之动态规划 字符串拆分问题相关的知识,希望对你有一定的参考价值。

         某种字符串处理语言允许程序员将一个字符串。。。原题如下图,最近在刷算法导论的题目,觉得这题有趣,写下自己的想法和大家分享一下。


                                                                                                            图1 

      动态规划算法首先要证明其满足动态规划算法的两个基本条件:1.最优子结构;2.重叠子问题。

首先来考虑重叠子问题,对于字符串S,假设第一次拆分点为L[k],则要变为s[0,L[k]]和s[L[k],max]两段字符串,处理代价为max,接下来就要s[0,L[k]]和s[L[k],max],每次处理方式又是相同的。

代价可以计为pay(s)=pay(s[0,L[k]])+pay(s[L[k],max])+max,当pay(s[0,L[k]])+pay(s[L[k],max])之和取到最小值时,就有最小值。故也满足最优子结构。

接下来,就要推导递推式,pay(s)=min(pay(s[0,L[k]])+pay(s[L[k])+max,k属于1到m.

我们可以先计算pay(S[L(i),L(i+2)])的值,

之后计算pay(S[L(i),L(i+3)])的值,

在计算pay(S[L(i),L(i+4)])

直到得到pay(s)的值。

这是基本思路,代码如下:

#include <iostream.h> 

int main()

	//输入部分
	cout<<"please input the length of the string: ";
	int n;
	cin>>n;
	cout<<"please input the 拆分点的个数与数目:";
	int m;
	cin>>m;
	int* l=new int(m+2);
	for(int i=1;i<=m;i++)
		cin>>l[i];
	l[0]=0;
	l[m+1]=n;
	int max_num=999999;
	//输入部分
	int s[100][100];//用于s[L(i)][L(j)]存储最小代价;
	//计算
	for(int j=0;j<=m;j++)	
	s[l[j]][l[j+1]]=0;
	int k,x,y;
  for ( k=2;k<=m+1;k++)

  	int q=m-k+1;
	  for( x=0;x<=q;x++)
				max_num=999999;
		  for ( y=1;y<k;y++)
				
				int temp	=s[l[x]][l[x+y]]+s[l[x+y]][l[x+k]]+l[x+k]-l[x];
					if (temp<max_num)
					
						s[l[x]][l[x+k]]=temp;
                        max_num=temp;
						
			
		  
				
  		
    cout<<"the answer : "<<s[0][l[m+1]];
	
	


 

以上是关于算法导论之动态规划 字符串拆分问题的主要内容,如果未能解决你的问题,请参考以下文章

豁然开朗经典算法之动态规划

算法导论——动态规划

算法导论 之 动态规划 - 装配线调度问题[C语言]

《算法导论》中动态规划求解钢条切割问题

算法导论精华总结 ~ 动态规划

算法导论之动态规划 签约棒球自由球员