数学排列好难--- QAQ的问题

本文探讨了一个关于计数问题的算法实现,通过组合数学的方法计算特定条件下的方案数量。问题涉及选择不同数量的阵地分配固定数量的士兵,考虑了阵地的选择与士兵分配的多种可能性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

问题 I: QAQ的问题
时间限制: 1 Sec  内存限制: 128 MB
提交: 11  解决: 3
[提交][状态][讨论版]
题目描述
有M个不同的阵地,每个阵地上可以留守任意个士兵(为非负数)。现在QAQ有N个士兵,他需要选择至少一个阵地才可以获得胜利。QAQ的一贯原则——让所有士兵留守在他选择的阵地上。问有多少种安排方案使得QAQ获得胜利。为了降低难度,QAQ在选择的阵地上不留守士兵也是合法的。


方案数的不同判定只能依据下面三条:
(1)选择的阵地数目不同
——选择1个阵地和选择2个阵地。
(2)选择的阵地不同
——选择阵地1、2和选择阵地2、3。
(3)在选择的阵地中任意两个阵地留守士兵数目不同
——阵地1有a人、阵地2有b人;阵地1有c人、阵地2有d人。其中a != c || b != d 且a、b、c、d均为非负数。




举个例子:有2个士兵和2个阵地,方案数为5。
(1)选择1个阵地方案数为2 —— 选择阵地1并留守2个士兵 或者 选择阵地2并留守2个士兵。
(2)选择2个阵地方案数为3 —— 在阵地1、2留守士兵人数为0 2、2 0、1 1。
这里要注意:不能依据每个阵地的人数来判定(1)里面的方案2 !0、!0 2和(2)的2 0、 0 2重复,因为前提选择的阵地数目不同。


输入
有多组测试数据,请处理到文件结束。


每组数据给定两个整数N和M,分别表示士兵人数和阵地数目。1 <= N, M <= 50。


输出
每组数据输出一个整数表示不同的方案数。由于结果可能很大,你只需要输出 % 777的结果。


解释一下,如果最后结果为777,你只需要输出777 % 777 = 0。


样例输入
2 2
46 37
1 1
样例输出
5
0

1


思路:循环选的阵地数k,1<=k<=m,从m中选k个,从k中选出t个(阵地中士兵不为0的)阵地,将n个士兵分到t个阵地中(c(n-1,t-1))。

公式:

C ( N , K ) = C ( N - 1 , K - 1 ) + C ( N - 1 , K ) ;


代码:

#include<cstdio> 
#include<cstring> 
#include<algorithm> 
using namespace std; 
int n,m; 
int c[60][60]; 
int A(int nn,int ii) 
{ 
    int ss=0; 
    for (int i=1;i<=ii;i++) 
    ss=(ss+c[ii][i]*c[n-1][i-1])%777; 
    return ss; 
} 
int main() 
{ 
  
    memset(c,0,sizeof(c)); 
    for (int i=0;i<55;i++) 
    c[i][0]=1; 
    for (int i=1;i<55;i++) 
    for (int j=1;j<=i;j++) 
    c[i][j]=(c[i-1][j-1]+c[i-1][j])%777; 
    while (~scanf("%d%d",&n,&m)) 
    { 
        int as=0; 
        for (int i=1;i<=m;i++) 
        as=(as+c[m][i]*A(n,i))%777; 
        printf("%d\n",as); 
    } 
    return 0; 
} 


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值