排列组合的去重问题

Posted Lis~

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了排列组合的去重问题相关的知识,希望对你有一定的参考价值。

题目描述

给出四堆石子,石子数分别为a,b,c,d。规定每次只能从堆顶取走石子,问取走所有石子的方案数。
 
 
 
 
 
 

输入描述:

在一行内读入四个由空格分隔的整数a,b,c,d, 输入均为不超过500的正整数>

输出描述:

输出一个整数表示答案,答案对109+7取模

输入

3 5 4 2

输出

2522520

备注

输入均为不超过500的正整数


题意:每次只能取一颗石子,然后有多少种不同的取石子方法,其中有一个顺序不同即视为不同顺序‘
思路:当时以为可以取多个被坑了,然后一直以为是一个博弈,后来才看懂题,把四堆石子分为四个队伍,然后问所有队员排列有多少种方法,但是因为队伍内的人员有重复,所以要进行去重
(a+b+c+d)!代表所有的数的全排列
(a+b+c+d)/(a!*b!*c!*d!)(去重公式)
(a+b+c+d)!代表所有的数的全排列

由于第一队有a个元素,所以a个元素的全排是重复的。
b,c,d同上。
得出最后的结果
(a+b+c+d)/(a!*b!*c!*d!)
#include<cstdio>
#include<iostream>
#include<cstring>
using namespace std;
typedef long long ll;
const ll N=2010,mo=1e9+7;
ll power(ll a,ll b){//快速幂 
    ll ans=1;
    while (b){
        if (b&1)ans=ans*a%mo;
        a=a*a%mo;
        b>>=1;
    }return ans;
}
ll jc(ll a){
    ll ans=1;
    for (ll i=1;i<=a;i++)ans=ans*i%mo;
    return ans;
}
ll ny(ll x){//逆元 
    return power(x,mo-2);
}
ll a,b,c,d;
int main(){
    cin>>a>>b>>c>>d;
    ll ans=jc(a+b+c+d);
    ans=ans*ny(jc(a))%mo*ny(jc(b))%mo*ny(jc(c))%mo*ny(jc(d))%mo;
    cout<<ans<<endl;
}

 

以上是关于排列组合的去重问题的主要内容,如果未能解决你的问题,请参考以下文章

常用的去重和排序

thinkphp 去重查询问题

计蒜之道2018复赛G(组合问题)

java 全排列,去重全排列,全组合

求教mongoDB怎么实现分组去重

LeetCode回溯算法#07子集问题I+II,巩固解题模板并详解回溯算法中的去重问题