题目描述
小L有严重的选择困难症。
早上起床后,需要花很长时间决定今天穿什么出门。
假设一共有k类物品需要搭配选择,每类物品的个数为Ai,每个物品有一个喜欢值Vj,代表小L对这件物品的喜欢程度。
小L想知道,有多少种方案,使得选出来的总喜欢值>M
需要注意,每类物品,至多选择1件,可以不选。

输入描述:
多组输入
每组数据第一行输入k M(k<=6,1<=M<=1e8),表示有多少类物品
接下来k行,每行以Ai(1<=Ai<=100)开头,表示这类物品有多少个,接下来Ai个数,第j个为Vj(1<=Vj<=1e8),表示小L对这类物品的第j个的喜欢值是多少。
输出描述:
每组输出一行,表示方案数
示例1
输入

复制
2 5
3 1 3 4
2 2 3
2 1
2 2 2
2 2 2
输出

复制
3
8

思路:
对搜索进行优化 当满足情况的时候 后面的选择都不影响最后结果大于m的结果,通过高中数学的排列组合思想,将结果数相乘即可。

#include<iostream>
#include<queue>
#include<vector> 
#include<cstdio>
#include<algorithm>
using namespace std;
typedef long long ll;
//--------------------------------------
int  k, m;
long long ans;

//--------------------------------------

int arrSize[10];
int arr[10][105];
void dfs(int step, int sum)
{

    //搜索的优化

    if (sum > m)//不管结果如何 
    {
        ll re = 1;
        //如果已经是最后一个了 直接会加到答案里面
        for (int i = step; i < k; i++)
        {
            re *=( arrSize[i]+1);//把数目相乘即可 记得把0乘上
          }
        ans += re;
        return;
    }
    if (step == k)//已经选完了 用来控制搜索的终止
    {
        return;
    }
    for (int i = 0; i <= arrSize[step]; i++)//把0 也包括进去 
    {
        dfs(step + 1, sum + arr[step][i]);
    }
}
int main()
{
    while (cin >> k >> m)
    {
        ans = 0;
        for (int i = 0; i < k; i++)//深度从0开始
        {
            cin >> arrSize[i];
            for (int j = 1; j <= arrSize[i]; j++)//第0个当做是不选的情况
            {
                cin >> arr[i][j];
            }
        }
        dfs(0, 0);
        cout << ans << endl;
    }
}
/*
4 1
2 2 2
2 2 2
3 2 2 2
5 2 2 2 2 2

*/