SSL_2408 比萨

题意

给出t种调料,还有n种规则,规则里的配料不能一起放,例如给出规则(1,2,3),说明(1,2,3)不能一起放,但是(1,2)是可以一起放的,如果给出规则(1,2),(1,2,3)是不能一起放的,现在求我们一共有多少种调法(包括不放调料)。

思路

我是先把规则给存起来,之后用搜索枚举出每种调法,再判断符不符合规则就好了。

代码

#include<cstdio>
int stop,ans,T,N,x,tot,yes[53][21],stack[101];
int check(int c)//判断是否符合规则,就自己理解吧
{
    if (tot==0) return 1;
    int f=1;    
    for (int i=1;i<=tot;i++)
    {
        f=1;
        for (int j=1;j<=yes[i][0];j++)
          for (int k=1;k<=c;k++)
            if (stack[k]==yes[i][j]) f++;
        if (f==yes[i][0]+1) {f=0;break;}
    }
    return f;
}
void dfs(int dep,int len)
{
    stack[len]=dep;//用一个数组存当前方案以便判断
    if (!check(len)) return;//不符合规则就反回
    ans++;//统计方案数
    for (int i=dep+1;i<=T;i++)
      dfs(i,len+1);//继续枚举方案
}
int main()
{
    scanf("%d%d",&T,&N);
    for (int i=1;i<=N;i++)
    {
        scanf("%d",&x);
        tot++;
        for (int j=1;j<=x;j++)
          scanf("%d",&yes[tot][j]),yes[tot][0]=x;//yes[tot]存每个规则,yes[][0]存这个规则的数字数量
    }
    for (int i=1;i<=T;i++)
      dfs(i,1);//枚举方案
    printf("%d",ans+1);//加上不用调料的
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值