题意:有十个人在玩LOL,总共有100个英雄,每个人可以选一个和BAN一个,问你们十个人有多少种不同的BAN选方案,取余1e9+7?输入5个01串表示我方五个人分别拥有的英雄,假设对面英雄全有。
①任意两个人不能选或BAN同一个英雄
②只能选自己有的英雄。
③12345召唤师选英雄12345和54321是不同的方案,12345召唤师BAN英雄12345和54321是相同的方案。
思路:统计第五个人有的英雄数,暴力枚举我方前四个人的选人,第五个人有的英雄数 - 被前四个人选到且自己拥有的英雄个数,累计这个结果就是我方选人的方案数记为ans。
对面五个人的选英雄方案数为A(95,5)。
我方BAN五个英雄的方案数为C(90,5),敌方BAN五个英雄的方案数为C(85,5)。
按照乘法计数原理可得ans * A(95, 5) * C(90, 5) * C(85, 5)就是答案。记得取模,乘一步取模一次。
#include<bits/stdc++.h>
using namespace std;
const int MAXN = 200005;
typedef long long ll;
const int MOD = 1000000007;
char s[6][105];
int a[6];
ll A(ll n, ll r)//排列数
{
ll sum = 1;
for (int i = 0; i < r; i++)
sum *= n-i;
return sum;
}
ll C(ll n, ll r)//组合数
{
ll sum = 1;
for (int i = 1; i <= r; i++)
sum = sum * (n+1-i)/i;
return sum;
}
int main()
{
while (~scanf("%s", s[0]))
{
for (int i = 1; i < 5; i++) scanf("%s", s[i]);
for (int i = 0; i < 5; i++) a[i] = count(s[i], s[i]+100, '1');
//for (int i = 0; i < 5; i++) printf("%d ", a[i]); printf("\n");
ll ans = 0;
for (int i0 = 0; i0 < 100; i0++)
{
if (s[0][i0] == '0') continue;
for (int i1 = 0; i1 < 100; i1++)
{
if (s[1][i1] == '0') continue;
if (i0 == i1) continue;
for (int i2 = 0; i2 < 100; i2++)
{
if (s[2][i2] == '0') continue;
if (i0 == i2 || i1 == i2) continue;
for (int i3 = 0; i3 < 100; i3++)
{
if (s[3][i3] == '0') continue;
if (i0 == i3 || i1 == i3 || i2 == i3) continue;
int cnt = 0;
if (s[4][i0] == '1') cnt++;
if (s[4][i1] == '1') cnt++;
if (s[4][i2] == '1') cnt++;
if (s[4][i3] == '1') cnt++;
ans = (ans + a[4] - cnt)%MOD;
}
}
}
}
ll tmp = A(95, 5) * C(90, 5) % MOD * C(85, 5) % MOD;
printf("%lld\n", ans*tmp%MOD);
}
return 0;
}
/*
0110011100011001001100011110001110001110001010010111111110101010010011010000110100011001001111101011
1000111101111110110100001101001101010001111001001011110001111110101000011101000001011100001001011010
0100101100011110011100110110011100111100010010011001111110101111111000000110001110000110001100001110
1110010101010001000110100011101010001010000110001111111110101010000000001111001110110101110000010011
1000010011111110001101100000101001110100011000111010011111110110111010011111010110101111011111011011
*/
//515649254