算法----动态规划(2)

基于动态规划的思想我们再来做几个练习

练习2:在一组数中选择几个数字使其加起来和最大,但是选中的几个数字不能相邻,求最大的和

以以下这组数据举栗子 

         

我们依旧是之前的思想:选或者不选!!!!!!

依旧是最优解OPT(i)代表到第i个元素最优解是什么

+代表选择第i个     -代表不选择第i个

我们发现这个展开图中依旧出现了重叠子问题  ,比如OPT(3)和OPT(4),那么我们就可以采用动态规划,避免使用递归重复计算

                                 OPT(i-2) + arr [i]  ;    //选择第i个元素

OPT(i)    =     max

                                  OPT(i-1)          //不选第i个元素

这就是该问题的递归式,那么递归出口应该是什么呢?

对了,当i=0时,OPT(i)=arr[0]   或者当i=1时,OPT(1) = max ( arr[0], arr[1] ); 

okkkkk,问题分析清楚了,上代码

//递归版本    时间复杂度O(2^n)
int RecOpt(int *arr,int i)
{
	if(i==0) return arr[0];
	else if(i==1) return max(arr[0],arr[1]);
	else return max(RecOpt(arr,i-2)+arr[i],RecOpt(arr,i-1));
}
int main()
{
	int arr[]={1,2,4,1,7,8,3};
	int len=sizeof(arr)/sizeof(arr[0]);
	cout<<RecOpt(arr,len-1)<<endl;
} 

接着看非递归版本

int NotRecOpt(int *arr,int i)
{
	if(i<0||arr==NULL)
		return -1;
	if(i==0)
		return arr[0];
	vector<int> maxsum(i+1);
	maxsum[0]=arr[0];
	maxsum[1]=max(arr[0],arr[1]);
	for(int j=2;j<=i;j++)
		maxsum[j]=max(maxsum[j-1],maxsum[j-2]+arr[j]);
	return maxsum[i];
}

猜你喜欢

转载自blog.csdn.net/Eunice_fan1207/article/details/89477447