Magic盒子(裸的递归回溯)

Magic盒子

Time Limit: 1 Sec   Memory Limit: 128 MB
Submit: 28   Solved: 9
[ Submit][ Status][ Web Board]

Description

现在ACMer有一个非常有魔法性的盒子,盒子的总的体积是40,使用该盒子你就可以很神奇地变出一些物品,但是这些物品的总体积必须是40才行。ACMer现在有n个想要得到的物品,每个物品的体积分别是a1,a2……an。ACMer可以从这些物品中选择一些,如果选出的物体的总体积是40,那么利用这个神奇的盒子,ACMer就可以得到这些物品。现在的问题是,ACMer有多少种不同的选择物品的方式呢?

Input

多组输入,输入的第一行是正整数n (1 <= n <= 20),表示不同的物品的数目。接下来的n行,每行有一个1到40之间的正整数,分别给出a1,a2……an的值。

Output

输出不同的选择物品的方式的数目。

Sample Input

3 
20
20
20

Sample Output

3

这是一道裸的递归回溯或者DP如果想不出来动态方程用回溯的方法是最简单的

我是用的回溯方法

# include <iostream>
# include <algorithm>
# include <set>
# include <map>
# include <vector>
# include <queue>
# include <numeric>
# include <string>
# include <cstring>


using namespace std;


int a[25];//物品
//int b[20];
int v[25];//标记
int sum = 0;
int n;
void bfs(int flag, int m)
{


    if(flag > 40)
    {
        return ;

    }

//体积等于40sum++并且跳出递归

    else if(flag == 40)
    {
sum++;
        return ;
    }


        for(int i = m; i < n; i++)
        {

  //          cout << "v[i] = " << v[i] << " i = " << i <<endl;

//v[i]标记如果为0表示我这个物品没用过

            if(!v[i])
            {

//这个代码的核心所在,用来模拟一种种情况
                flag += a[i];
                v[i] = 1;
bfs(flag, i + 1);
                v[i] = 0;
               flag -= a[i];
            }
        }


}


int main(int argc, char *argv[])
{


    while(cin >>n)
    {
       memset(a, 0, sizeof(a));
       memset(v, 0, sizeof(v));


       sum = 0;
      for(int i = 0; i < n; i++)
      {
          cin >> a[i];

      }

//把我累计的体积和当前用哪个盒子穿进去

//因为一开始都为0所以传零

       bfs(0, 0);
        cout << sum  << endl;
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值