基础算法之分治算法

分治算法的基本思想的是将一个规模为N的问题分解为K个规模较小的问题,这些子问题是相互独立且与原问题性质相同的

 

例1-1计数问题

  给定2个数a,b计算出1在a和b之间出现的次数

 

算法思想:

        计算出1在0-a和0-b之间出现的次数,然后相减

例如在计算0-197之间的数

1.首先计算190-197之间个位数上出现1的次数

2.然后计算180-189上的1出现的个数

3然后递归 到18求解 权值*10 

 

源代码如下:

   

#include<stdio.h>
#define N 10
int count[N];
int value=1;
void Deal(int k)
{
    if(k<=0)return;
    int one,ten;
    one=k%10;
    k/=10;
    ten=k;

    for(int i=0;i<=one;i++)  //第一步
    {
        count[i]+=value;
    }

    while(ten)  //第一步
    {
        count[ten%10]+=value*(one+1);
        ten/=10;
    }

    for(int j=0;j<10;j++) //第二步
    {
        count[j]+=value*k;
    }
    count[0]-=value;
    value*=10;  //第三步
    Deal(k-1);   //第三步

}
int main()
{
    int a,b;
    while(scanf("%d%d",&a,&b)!=EOF)
    {
        for(int i=0;i<10;i++)
        count[i]=0;
        value=1;
        Deal(b);
        value=-1;
        Deal(a-1);
        printf("%d\n",count[1]);

    }
    

    return 0;
}

 例1-2整数划分问题

   在整数划分的问题中,可以采取递归的方式解决,也可以采取剪枝搜索的方式解决,最好的还是采动态规划的方式解决

搜索剪枝的代码:

   

int fun(int n,int k)
{
    if(n<k)return 0;
    if(n==k)return 1;
    int sum=1;
    for(int i=n-1;i>=n/2;i--)
    {
        if(i>=k&&(n-i)>=k)
        sum+=fun(i,n-i);
    }
    return sum;
}

 

动态规划的代码:

 

void  Dp(int n)
{
    int i,j;
    for(i=0;i<=n;i++)
    {
        A[i][1]=1;
    }

    for(i=1;i<=n;i++)
    {
        for(j=1;j<=n;j++)
        {
            if(j>i)A[i][j]=A[i][i];
            if(j==i)A[i][j]=1+A[i][i-1];
            if(i>j)A[i][j]=A[i][j-1]+A[i-j][j];
        }
    }

    printf("Dp res is %d\n",A[n][n]);

}

 

posted on 2013-04-05 14:34  AAAAAApple  阅读(232)  评论(0编辑  收藏  举报

导航