元始天尊 发表于 2014-7-26 17:08:04

子集合数问题的回溯解法

    这几天学回溯法,稍微有点心得了,其实就是按深度优先遍历问题解树,而分支界限法则是按广度优先遍历
    给定n=4 W={11,13,24,7} M=31   则子集合数问题的解为X={0,0,1,1} 和X={1,1,0,1}
X只能取{0 1},相应地是选或者不选该数,按照选和不选,就可以构造一颗解树,利用回溯法遍历该树。
复杂度本应该是O(2^n)但是由于分支裁剪以后,下面的子树都不用遍历了,所以复杂度应该远小于这个
下面是我的代码:
// sumofsub.cpp : Defines the entry point for the console application.
//
#include <stdio.h>

int main(int argc, char* argv[])
{
        int arr={5,10,12,13,15,18};
        int x={0,0,0,0,0,0};//0:左子树没走过 1:左子树走过,右子树没走过 2:左子树走过,右子树走过
        int sum=30;
        int totalsum=0;
        int n=6;
        for(int i=0;i<n;i++)
        {
                totalsum+=arr;
        }

        int layer=0;

        while(layer>=0)
        {
                if(totalsum >= sum)
                {
                        if(arr == sum)
                        {
                                for(int i=0;i<layer;i++)
                                {
                                        if(x == 1)
                                                printf("%d ",arr);
                                }
                                printf("%d\n",arr);
                                x=2;
                        }
                        else if(arr < sum && x != 2)
                        {//走左子树
                                if(x == 0)//如果左子树没走过,走左子树
                                {
                                        x=1;
                                        sum -= arr;
                                }
                                else
                                {
                                        x=2;
                                        x=0;
                                }
                                totalsum -= arr;
                                layer++;
                                continue;
                        }
                        else
                        {
                                x=2;
                        }
                }
                else
                {
                        x=2;
                }

                if(x == 2)
                {
                        //向上层回溯
                        layer--;
                        if(layer>=0)
                        {
                                if(x < 2)
                                        sum += arr;
                                totalsum += arr;
                        }
                }
        }

        getchar();
        return 0;
}
页: [1]
查看完整版本: 子集合数问题的回溯解法