题目描述
小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
*/
京公网安备 11010502036488号