Locked Treasures(组合数学思维)uva 6873

A group of n (1 ≤ n ≤ 30) bandits hid their stolen treasure in a room. The treasure needs to be locked away until there is a need to retrieve it. Since the bandits do not trust each other, they wanted to ensure that at least m (1 ≤ m ≤ n) of the bandits must agree in order to retrieve the treasure.
They have decided to place multiple locks on the door such that the door can be opened if and only if all the locks are opened. Each lock may have up to n keys, distributed to a subset of the bandits. A group of bandits can open a particular lock if and only if someone in the group has a key to that lock.
Given n and m, how many locks are needed such that if the keys to the locks are distributed to the bandits properly, then every group of bandits of size at least m can open all the locks, and no smaller group of bandits can open all the locks?
For example, if n = 3 and m = 2, only 3 locks are needed—keys to lock 1 can be given to bandits 1 and 2, keys to lock 2 can be given to bandits 1 and 3, and keys to lock 3 can be given to bandits 2 and 3. No single
bandit can open all the locks, but any group of 2 bandits can open all the locks. You should also convince yourself that it is not possible to satisfy the requirements with only 2 locks.

Input
The first line of input contains a positive integer indicating the number of cases to follow. Each case is
specified by the two integers n and m on one line.

Output
For each line of input, print on one line the minimum number of locks needed.

Sample Input
4
3 2
5 1
10 7
5 3
Sample Output
3
1
210
10

根据样例可以推出结果是C(n,m-1)
至于为什么是这样 大牛的分析。。不怎么能看懂。。而且推了公式,有谁看懂了大佬的方法记得跟我用简单的方式跟我说说。。我太笨了。。

这里写图片描述

我的想法是 额。。。我是这样理解的。。。如果是4个人 每两个人就能开的话
是每个人都有3把钥匙吗
1 2 3
1 2 4
1 3 4
2 3 4 就是每个人都缺少的钥匙搭配种类C(4,1) 如果是5个人 每3个就能开的话 缺少钥匙搭配种类就是 C(5,2)。我不知道我这样理解对不对。。你那个说法。。。没有具体样例我想不懂。。但是这样我不知道为什么缺少的钥匙方案数等于锁数。大佬跟我说。
应该改成
应该是
第一把锁的钥匙给 1 2 3
第二把锁的钥匙给 1 2 4
第三把锁的钥匙给 1 3 4
第四把锁的钥匙给 2 3 4
接着我恍然大悟,对啊这样就能把缺少的方案数配对起来。这样说种类数的定义应该改为不给钥匙的人的种类数。就好像5 3,不给两个人,不给的两个人种类搭配数有C(5,2) 所以至少锁的个数为C(5,2)

最后打个表就能出来了

#include <iostream>
using namespace std;
int C[40][40];
int main()
{
    int t;
    cin>>t;
    C[0][0]=1;
    for(int i=1;i<=35;i++)
    {
        C[i][0]=1;
        for(int j=1;j<=35;j++)
            C[i][j]=C[i-1][j]+C[i-1][j-1];
    }
    while(t--)
    {
        int n,m;
        cin>>n>>m;
        printf("%d\n",C[n][m-1] );
    }

}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值