分治法

1.分治法求全排列

void perm(char a[],int start,int end)
{
    if(start==end)
    {
        printf("%s
",a);
        return;
    }
    else
    {
        for(int i=start;i<=end;i++)
        {
            swap(a[i],a[start]);
            perm(a,start+1,end);
            swap(a[i],a[start]);
        }
    }
}
//有重复元素的
#include <iostream>
#include <algorithm>
#include <cstdio>
#include<cstring>
using namespace std ;
int ok(char str[],int a ,int b )
{
    if(b>a)
    for(int i=a;i<b;i++)

        if(str[i]==str[b])
            return 0;
    return 1;
}
void perm(char str[],int k,int m)
{
    if(k==m)
    {
        printf("%s
",str);
        return ;
    }
    else 
    for(int i=k;i<=m;i++)
        if(ok(str,k,i))//判断第i个元素是否在str[k,i-1]中出现过
        {
            swap(str[k],str[i]);
            perm(str,k+1,m);
            swap(str[k],str[i]);
        }
}
int main()
{
    char str[505];
    scanf("%s",str);
    perm(str,0,strlen(str)-1);
    return 0;
}


2.分治法求整数划分

int q(int n,int m)
{
    if(n==1||m==1)
        return 1;
    else if(n<m)
        return q(n,n);
    else if(n==m)
        return 1+q(n,n-1);
    else
        return q(n,m-1)+q(n-m,m);
}
//输出序列
#include <stdio.h>
int mark[10];
int n;
void Divid(int now,int k,int prio)  
 {
    //now记录当前长度,k记录深度,prio记录前一个的值。
    int i;
    if(now > n) return;  //不合适,返回。
    if(now == n)
    {
        for(i = 0; i < k-1; i++)
            printf("%d+",mark[i]);
        printf("%d
",mark[i]);
    }
    else
    {
        for(i = prio; i > 0; i--)
        {
               mark[k]=i;
               now+=i;
               Divid(now,k+1,i);
               now-=i;
        }
    }
 }
int main()
{
    scanf("%d",&n);
    Divid(0,0,n-1);
    return 0;
}



            
原文地址:https://www.cnblogs.com/nickqiao/p/7583391.html