FZU 2086 Redcarnation

来源:互联网 发布:金山数据浏览小精灵 编辑:程序博客网 时间:2024/06/05 08:13

Description
Jack最近喜欢到学校餐厅吃饭,好吃干净还便宜。

在学校餐厅,有a种汤,b种饭,c种面条,d种荤菜,e种素菜。

为了保证膳食搭配,Jack每顿饭都会点1~2样荤菜,1~2样素菜(不重复)。同时,在Jack心情好的时候,会点一样饭,再配上一种汤。在心情不好的时候,就只吃一种面条。

因为经济有限,Jack每次点餐的总价在min~max之间。Jack想知道,总共有多少种不同的点餐方案。

Input
输入数据第一行包含一个整数T,表示测试数据的组数,对于每组测试数据:
第一行为整数a,b,c,d,e(0 < a,b,c,d,e<=10)
第二行为a个大于零的整数,表示a种汤的价格
第三行为b个大于零的整数,表示b种饭的价格
第四行为c个大于零的整数,表示c种面条的价格
第五行为d个大于零的整数,表示d种荤菜的价格
第六行为e个大于零的整数,表示e种素菜的价格
第七行为两个整数min max,表示每次点餐的价格范围

Output
对于每组测试数据,输出一行,包含一个整数,表示点餐方案数。

Sample Input
1
2 2 2 2 2
2 3
3 1
5 2
1 4
3 6
5 8
Sample Output
3

我看网上这道题好多都是用模拟,枚举写,不过我感觉用dfs写应该更简单一些。

我的思路:将 汤,饭,面条,荤菜,素菜,各自作为 dfs 的一层,我们从第一层 “汤”开始往下搜索,大家可以将这个dfs看成一颗深度为五的树。在这里需要注
意的是 1~2 层在心情不好的时候不取值 ,3 层在心情好的时候不取值。 好了下面
贴代码。

#include <iostream>#include <algorithm>#include <cstdio>#include <cstdlib>#include <cstring>using namespace std;int s[6][15],arr[7],t,num;int a,b,c,d,e,i,ma,mi;int dfs(int i,int is,int money);//i代表当前层数,is是心情好坏。int main(){    int i;    cin>>t;    while(t--)    {        cin>>arr[1]>>arr[2]>>arr[3]>>arr[4]>>arr[5];  //arr 数组存a,b,c,d,e 的值。        for(i=1; i<=arr[1]; i++)            cin>>s[1][i];        for(i=1; i<=arr[2]; i++)            cin>>s[2][i];        for(i=1; i<=arr[3]; i++)            cin>>s[3][i];        for(i=1; i<=arr[4]; i++)            cin>>s[4][i];        for(i=1; i<=arr[5]; i++)            cin>>s[5][i];        cin>>mi>>ma;        num = 0;        dfs(1,1,0);        dfs(1,2,0);        cout<<num<<endl;    }    return 0;}int dfs(int i,int is,int money){   if(money > ma) return 0;//剪枝   if(i==6) //   {       if(money>=mi && money<=ma)            num++;      //   printf("  num=%d  money=%d ",++num,money);       return 0;   }   if(i==1 && is==2)//is==2 代表心情不好,故不取1~2的值,也就是 汤和饭的值   {       dfs(i+1,is,money);  return 0;   }   if(i==2 && is==2) //i==2 代表饭   {       dfs(i+1,is,money);  return 0;   }   if(i==3 && is==1)//is==1 代表心情好,不取面条,直接下一层。   {        dfs(i+1,is,money); return 0;   }   for(int j=1; j<=arr[i]; j++)// 对第 i 种食物取一种      dfs(i+1,is,money+s[i][j]);   if(i==4 || i==5) // 如果是荤素菜,还有取两种的情况      for(int j=1; j<=arr[i]; j++)        for(int k=j+1; k<=arr[i]; k++)           dfs(i+1,is,money+s[i][j]+s[i][k]);   return 0;}
0 0