递归与分治策略

递归与分治策略

凡治重如治寡,分数是也————孙子兵法
分治的设计思想:将一个直接解决的大问题,分割成一些规模较小的相同问题,以便各个击破,分而治之。个子问题之间既是相互独立的,彼此之间也存在联系;
递归的设计思想:将求出的小规模问题的解合并为一个更大规模的问题的解,自底向上逐步求出原来问题的解。
递归的概念:直接或者间接的调用自身的算法称为递归,用函数自身给出定义的函数叫做递归函数。
Action 1:
求解从1加到的100的总和;
常规做法

int sum=0;
for(int i=0;i<=100;i++)
{
sum+=i;
}
return sum;

递归做法

public int add(int n)
{
    if(n>0)
    {
    return add(n-1)+n;
    }
    return 0;
}

递归的必备二要素:1,递归函数(Action1中add方法)2边界条件(Action1中if判断语句)。只有满足了这两个要素,才能在有限次计算后得出结果。
分治与递归的关系:分治是把一个大问题分解成许多子问题来各个击破,然后利用递归实现子问题然后组装成原大问题。至于分治中大问题的拆分依据,则相当于Action1中的if判断语句。
Action2:
整数划分问题:将正整数n表示成一系列正整数之和:n=n1+n2=…+nk,其中n1>=n2>=nk,k>=1;正整数n 的这种表示方法称为正整数的n 的划分。求正整数n 的不同划分个数。
例如:正整数6有如下11种不同的划分:
6; 5+1; 4+2; 4+1+1; 3+3; 3+2+1; 3+1+1+1;
2+2+2; 2+2+1+1; 2+1+1+1+1; 1+1+1+1+1+1
首先寻找递归的二要素。本题问题本身不具备明显的递归关系,因此考虑用划分数来作为边界条件。然后建立递归函数q(n,m)n>=1,m>=1;
1:m=1或者n=1,都只有一种情况,既子项全部为1. q(n,m)=1.
2:m>n,m大于n 没意义,于是函数变为q(n,m)=q(n,n);
3:m=n,转换成m《n的情况+1. 既q(n,m)= q(n,n)= q(n,n-1)+1;
4:1《m《n,转换成按照(m-1)的划分加上独自以m的划分,(m-1)划分为q(n,m-1),独自以m的划分的总数为q(n-m,m)。因此此种划分结果为q(n,m)=q(n,m-1)+q(n-m,m);

#include "stdafx.h"
#include <stdio.h>
#include <iostream>
using namespace  std;
int sum(int n,int m)
{
if (m==1||n==1)
return 1;
if(m>n)
return sum(n,n);
if(m==n)
return sum(n,n-1)+1;
if(m>1&&m<n)
return sum(n,m-1)+sum(n-m,m); 
}

int _tmain(int argc, _TCHAR* argv[])
{
int i= sum(6,6);
cout<<i<<endl;
return 0;
}

运行结果:11 正确。

    原文作者:递归与分治算法
    原文地址: https://blog.csdn.net/tiefeng0606/article/details/50206169
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞