C# 数组之回溯法

很多数排列组合问题都可以用回溯法来解决,回溯相比上面方法的优点就是减少可行解搜索的范围,因为回溯一旦发现当前解不满足条件就会停止搜索,回溯并进入下一个分支进行搜索,比上面的方法快很多,这里使用的是回溯法中的子集树模型。对于数组中任意一个元素,先将其放入结果集中,如果当前和不超出给定和,那就继续考察下一个元素,如果超出给定和,则舍弃当前元素。如此往复,直到找到所有可行解。

首先定义一个标志位数组flag[],flag[i]如果为true,则表示a[i]在当前解中,如果flag[i]为false则表示不在。这个数组元素个数与数组a的元素个数相同。(#add,当然此标识也可以与数组元素构成结构体,然后放入数组)

        string outputStr = "";
        bool[] flag = new bool[100];
        /// <summary>
        /// 回溯法
        /// </summary>
        /// <param name="a">a: 待搜索的数组</param>
        /// <param name="n">n: 数组元素个数</param>
        /// <param name="t">t: 已经存储的元素个数</param>
        /// <param name="sum">sum: 给定的和</param>
        public void FixedSum(int[] a,int n,int t,int sum) {
            if (sum == 0)
            {
                Output(a, t);
                outputStr += "\r\n";//分割换行
            }
            else
            {
                if (t == n)
                {
                    return;
                }
                else
                {
                    flag[t] = true;
                    if (sum - a[t] >= 0)
                        FixedSum(a, n, t + 1, sum - a[t]);
                    //超出    
                    flag[t] = false;
                    if (sum >= 0)
                        FixedSum(a, n, t + 1, sum);
                }
            }

        }
        /// <summary>
        /// 输出这种组合
        /// </summary>
        /// <param name="a"></param>
        /// <param name="n"></param>
        public void Output(int[] a, int n)
        {
            for (int i = 0; i < n; i++)
            {
                if (flag[i])
                    outputStr += a[i] + ",";
            }

        }


       int[] a = new int[20];
       for (int i = 1; i <=20; i++)
        {
              a[i - 1] = i;
       }
       FixedSum(a, 20, 0, 10);
       MessageBox.Show(outputStr);//弹出结果


  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值