题意:有十个人在玩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